SlideShare a Scribd company logo
Go on!
3 June 2017
Vadim Petrov
Software engineer, Juno
Events collector
The microservice receives events from mobile clients by HTTP, collects them in a batch of
events and pass it to some 3rd-party system.
Microservice composition
Let's write some code
All further code is real and runnable.
You can nd it on GitHub.
github.com/Barberrrry/go-on-presentation(https://github.com/Barberrrry/go-on-presentation)
Processor
Fake processor
Create fake processor with random processing time up to 200 ms.
package processor
type Batch []string
type Fake struct{}
func (f *Fake) Process(batch Batch) {
if len(batch) == 0 {
return
}
// Fake process time
time.Sleep(time.Duration(rand.Intn(200)) * time.Millisecond)
}
That's enough for processor.
Collector
Collector v1: naive plan
Use a slice as a bu er
Append incoming data to the bu er
If bu er size reaches N, ush the bu er to Processor
Collector v1: types
package collector
type Processor interface {
Process(processor.Batch)
}
type Collector struct {
Processor Processor
MaxBatchSize int
buffer processor.Batch
}
Collector v1: collect
func (c *Collector) Collect(payload string) {
c.buffer = append(c.buffer, payload)
log.Printf("collected: %s", payload)
if len(c.buffer) >= c.MaxBatchSize {
c.flush(c.buffer)
c.buffer = nil
}
}
func (c *Collector) flush(batch processor.Batch) {
t := time.Now()
c.Processor.Process(batch)
log.Printf("flushed %d payloads in %s", len(batch), time.Since(t))
}
Collector v1: run
func main() {
collector := &collector.Collector{
Processor: &processor.Fake{},
MaxBatchSize: 2,
}
for i := 1; i <= 5; i++ {
collector.Collect(fmt.Sprintf("event_%d", i))
}
} Run
Collector v1: conclusion
Resolution: bad :(
Problem:
Function Collect() waits for Processor each N calls
To be xed:
Processor shouldn't block Collect()
Let's make Collector concurrent.
Concurrency
What is concurrency?
Concurrency is the composition of independently executing computations.
Concurrency is a way to design software.
Concurrency is not parallelism, although it enables parallelism.
Concurrency is about structure, parallelism is about execution.
Go has rich support for concurrency using goroutines and channels.
Goroutines
Goroutine is an independently executing function, launched by a go statement.
go func() {
fmt.Println("Hi!")
}()
It's very cheap.
It's practical to have thousands, even hundreds of thousands of goroutines.
Gouroutine is not OS thread.
Scheduler
Scheduler runs N contexts. N is con gurable. It may be 1 context.
Each context is running as OS thread.
Each context has own queue of goroutines.
Context stops goroutine execution on any blocking operation and starts next one from the
queue.
Communication
Goroutines without any input or output are useless.
Multiple goroutines require communication.
Don't communicate by sharing memory, share memory by communicating.
Instead of using locks to mediate access to shared data, use channels to pass data between
goroutines.
Channels
A channel in Go provides a connection between two goroutines, allowing them to
communicate.
Channel values may have any type, even other channel.
A channel is a blocking queue with de ned length.
Channel bu er
Bu ered channel
c := make(chan string, 5)
Unbu ered channel
c := make(chan string)
Collector v2
Collector v2: plan
Implement worker
Use channel to split incoming payloads among workers
Worker has own bu er and ush it when ready
Run several concurrent workers
Collector v2: collector
Add collector attributes and use channel as queue of incoming payloads.
type (
Collector struct {
Processor Processor
MaxBatchSize int
WorkersCount int
QueueSize int
payloadsQueue chan string
}
)
Collector v2: worker
Create worker() function with own bu er inside. Worker will ush bu er when it's ready.
func (c *Collector) worker(id int) {
var buffer processor.Batch
log.Printf("worker_%d start", id)
for payload := range c.payloadsQueue {
buffer = append(buffer, payload)
if len(buffer) >= c.MaxBatchSize {
c.flush(id, buffer)
buffer = nil
}
}
}
Collector v2: run workers
Collect() just writes payload to queue.
Create Run() function which will init queue channel and start N workers.
func (c *Collector) Collect(payload string) {
c.payloadsQueue <- payload
log.Printf("collected: %s", payload)
}
func (c *Collector) Run() {
log.Print("collector start")
c.payloadsQueue = make(chan string, c.QueueSize)
for i := 0; i < c.WorkersCount; i++ {
go func(id int) {
c.worker(id)
}(i)
}
}
Collector v2: run
func main() {
collector := &collector.Collector{
Processor: &processor.Fake{},
MaxBatchSize: 2,
WorkersCount: 2,
QueueSize: 1000,
}
collector.Run()
for i := 1; i <= 5; i++ {
collector.Collect(fmt.Sprintf("event_%d", i))
}
time.Sleep(200 * time.Millisecond)
} Run
Collector v2: conclusion
Resolution: better, but still not good
Fixed:
Function Collect() is not blocked anymore by Processor
Workers are concurrent
Problems:
Bu er is ushed only when reaches max batch size
To be xed:
Flush bu er after some timeout since last ush
Select
Select
The select statement waits on multiple communication operations.
A select blocks until one of its cases can run, then it executes that case.
It chooses one at random if multiple are ready.
If all cases are not ready, default happens.
values := make(chan int, 10)
quit := make(chan struct{})
for {
select {
case v := <-values:
fmt.Println(v)
case <-quit:
return
default:
time.Sleep(time.Second)
}
}
Collector v3. Final.
Collector v3: plan
Add ush interval as Collector parameter
Force ush periodically
Collector v3: collector
Add ush interval as Collector parameter.
type (
Collector struct {
Processor Processor
WorkersCount int
MaxBatchSize int
QueueSize int
FlushInterval time.Duration
payloadsQueue chan string
}
)
Collector v3: ush timer
func (c *Collector) worker(id int) {
var buffer processor.Batch
timer := time.NewTimer(c.FlushInterval)
for {
select {
case payload := <-c.payloadsQueue:
buffer = append(buffer, payload)
if len(buffer) >= c.MaxBatchSize {
c.flush(id, buffer, "size")
buffer = nil
timer.Reset(c.FlushInterval)
}
case <-timer.C:
c.flush(id, buffer, "timer")
buffer = nil
timer.Reset(c.FlushInterval)
}
}
}
Collector v3: run
func main() {
collector := &collector.Collector{
Processor: &processor.Fake{},
MaxBatchSize: 2,
WorkersCount: 2,
QueueSize: 1000,
FlushInterval: 200 * time.Millisecond,
}
collector.Run()
for i := 1; i <= 5; i++ {
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) // Fake delay
collector.Collect(fmt.Sprintf("event_%d", i))
}
time.Sleep(300 * time.Millisecond)
} Run
Collector v3: conclusion
Resolution: good enough
HTTP server
HTTP handler
Read HTTP request body and collect it by collector.
func NewCollectorHandler(d *collector.Collector) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
payload, err := ioutil.ReadAll(req.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
d.Collect(string(payload))
}
}
Start server
func main() {
collector := &collector.Collector{
Processor: &processor.Fake{},
MaxBatchSize: 5,
WorkersCount: 3,
QueueSize: 10000,
FlushInterval: 5 * time.Second,
}
collector.Run()
http.ListenAndServe("localhost:9090", server.NewCollectorHandler(collector))
}
Go on!
Let's run microservice and see how it works.
Conclusions
Go provides instruments to make complex things easy.
Concurrent code enables runtime parallelism.
Goroutines and channels are easy to use.
But don't overuse these ideas. Always use the right tool for the job.
Questions?
This presentation slides and code:
github.com/Barberrrry/go-on-presentation(https://github.com/Barberrrry/go-on-presentation)
Concurrency in Go
www.golang-book.com/books/intro/10(https://www.golang-book.com/books/intro/10)
golang.org/doc/e ective_go.html#concurrency(https://golang.org/doc/e ective_go.html#concurrency)
"Go Concurrency Patterns" by Rob Pike
www.youtube.com/watch?v=f6kdp27TYZs(https://www.youtube.com/watch?v=f6kdp27TYZs)
"Concurrency is not parallelism" by Rob Pike
blog.golang.org/concurrency-is-not-parallelism(https://blog.golang.org/concurrency-is-not-parallelism)
Thank you
Vadim Petrov
Software engineer, Juno
vadim.petrov@gmail.com(mailto:vadim.petrov@gmail.com)
https://www.facebook.com/barberry(https://www.facebook.com/barberry)
Go on!

More Related Content

What's hot

Golang design4concurrency
Golang design4concurrencyGolang design4concurrency
Golang design4concurrency
Eduardo Ferro Aldama
 
Ntp cheat sheet
Ntp cheat sheetNtp cheat sheet
Ntp cheat sheet
csystemltd
 
tokyotalk
tokyotalktokyotalk
tokyotalk
Hiroshi Ono
 
Exploitation of counter overflows in the Linux kernel
Exploitation of counter overflows in the Linux kernelExploitation of counter overflows in the Linux kernel
Exploitation of counter overflows in the Linux kernel
Vitaly Nikolenko
 
GoLang & GoatCore
GoLang & GoatCore GoLang & GoatCore
GoLang & GoatCore
Sebastian Pożoga
 
MessagePack(msgpack): Compact and Fast Serialization Library
MessagePack(msgpack): Compact and Fast Serialization LibraryMessagePack(msgpack): Compact and Fast Serialization Library
MessagePack(msgpack): Compact and Fast Serialization Library
Takatoshi Kondo
 
Go破壊
Go破壊Go破壊
Go破壊
Hattori Hideo
 
Demystifying the Go Scheduler
Demystifying the Go SchedulerDemystifying the Go Scheduler
Demystifying the Go Scheduler
matthewrdale
 
[JAM 1.2] Design & Multitasking (Andrew Solovey)
[JAM 1.2] Design & Multitasking (Andrew Solovey)[JAM 1.2] Design & Multitasking (Andrew Solovey)
[JAM 1.2] Design & Multitasking (Andrew Solovey)
Evgeny Kaziak
 
Why learn Internals?
Why learn Internals?Why learn Internals?
Why learn Internals?
Shaul Rosenzwieg
 
The async/await concurrency pattern in Golang
The async/await concurrency pattern in GolangThe async/await concurrency pattern in Golang
The async/await concurrency pattern in Golang
Matteo Madeddu
 
GoLightly: A Go Library For Building Virtual Machines
GoLightly: A Go Library For Building Virtual MachinesGoLightly: A Go Library For Building Virtual Machines
GoLightly: A Go Library For Building Virtual Machines
Eleanor McHugh
 
Storm
StormStorm
Note
NoteNote
Building a DSL with GraalVM (VoxxedDays Luxembourg)
Building a DSL with GraalVM (VoxxedDays Luxembourg)Building a DSL with GraalVM (VoxxedDays Luxembourg)
Building a DSL with GraalVM (VoxxedDays Luxembourg)
Maarten Mulders
 
Unpack mechanism of the msgpack-c
Unpack mechanism of the msgpack-cUnpack mechanism of the msgpack-c
Unpack mechanism of the msgpack-c
Takatoshi Kondo
 
Advanced cocos2d
Advanced cocos2dAdvanced cocos2d
Advanced cocos2d
Keisuke Hata
 
Concurrency in Go by Denys Goldiner.pdf
Concurrency in Go by Denys Goldiner.pdfConcurrency in Go by Denys Goldiner.pdf
Concurrency in Go by Denys Goldiner.pdf
Denys Goldiner
 
Coding in GO - GDG SL - NSBM
Coding in GO - GDG SL - NSBMCoding in GO - GDG SL - NSBM
Coding in GO - GDG SL - NSBM
Raveen Perera
 
#2 (UDP)
#2 (UDP)#2 (UDP)
#2 (UDP)
Ghadeer AlHasan
 

What's hot (20)

Golang design4concurrency
Golang design4concurrencyGolang design4concurrency
Golang design4concurrency
 
Ntp cheat sheet
Ntp cheat sheetNtp cheat sheet
Ntp cheat sheet
 
tokyotalk
tokyotalktokyotalk
tokyotalk
 
Exploitation of counter overflows in the Linux kernel
Exploitation of counter overflows in the Linux kernelExploitation of counter overflows in the Linux kernel
Exploitation of counter overflows in the Linux kernel
 
GoLang & GoatCore
GoLang & GoatCore GoLang & GoatCore
GoLang & GoatCore
 
MessagePack(msgpack): Compact and Fast Serialization Library
MessagePack(msgpack): Compact and Fast Serialization LibraryMessagePack(msgpack): Compact and Fast Serialization Library
MessagePack(msgpack): Compact and Fast Serialization Library
 
Go破壊
Go破壊Go破壊
Go破壊
 
Demystifying the Go Scheduler
Demystifying the Go SchedulerDemystifying the Go Scheduler
Demystifying the Go Scheduler
 
[JAM 1.2] Design & Multitasking (Andrew Solovey)
[JAM 1.2] Design & Multitasking (Andrew Solovey)[JAM 1.2] Design & Multitasking (Andrew Solovey)
[JAM 1.2] Design & Multitasking (Andrew Solovey)
 
Why learn Internals?
Why learn Internals?Why learn Internals?
Why learn Internals?
 
The async/await concurrency pattern in Golang
The async/await concurrency pattern in GolangThe async/await concurrency pattern in Golang
The async/await concurrency pattern in Golang
 
GoLightly: A Go Library For Building Virtual Machines
GoLightly: A Go Library For Building Virtual MachinesGoLightly: A Go Library For Building Virtual Machines
GoLightly: A Go Library For Building Virtual Machines
 
Storm
StormStorm
Storm
 
Note
NoteNote
Note
 
Building a DSL with GraalVM (VoxxedDays Luxembourg)
Building a DSL with GraalVM (VoxxedDays Luxembourg)Building a DSL with GraalVM (VoxxedDays Luxembourg)
Building a DSL with GraalVM (VoxxedDays Luxembourg)
 
Unpack mechanism of the msgpack-c
Unpack mechanism of the msgpack-cUnpack mechanism of the msgpack-c
Unpack mechanism of the msgpack-c
 
Advanced cocos2d
Advanced cocos2dAdvanced cocos2d
Advanced cocos2d
 
Concurrency in Go by Denys Goldiner.pdf
Concurrency in Go by Denys Goldiner.pdfConcurrency in Go by Denys Goldiner.pdf
Concurrency in Go by Denys Goldiner.pdf
 
Coding in GO - GDG SL - NSBM
Coding in GO - GDG SL - NSBMCoding in GO - GDG SL - NSBM
Coding in GO - GDG SL - NSBM
 
#2 (UDP)
#2 (UDP)#2 (UDP)
#2 (UDP)
 

Similar to Go on!

Web streams
Web streamsWeb streams
Web streams
Vladimir Shevchuk
 
Go Concurrency Patterns
Go Concurrency PatternsGo Concurrency Patterns
Go Concurrency Patterns
ElifTech
 
Writing a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdfWriting a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdf
RomanKhavronenko
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring framework
Sunghyouk Bae
 
Async fun
Async funAsync fun
Go and Uber’s time series database m3
Go and Uber’s time series database m3Go and Uber’s time series database m3
Go and Uber’s time series database m3
Rob Skillington
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
Qiangning Hong
 
gRPC in Go
gRPC in GogRPC in Go
gRPC in Go
Almog Baku
 
Pemrograman Python untuk Pemula
Pemrograman Python untuk PemulaPemrograman Python untuk Pemula
Pemrograman Python untuk Pemula
Oon Arfiandwi
 
FreeRTOS
FreeRTOSFreeRTOS
FreeRTOS
Ankita Tiwari
 
Router Queue Simulation in C++ in MMNN and MM1 conditions
Router Queue Simulation in C++ in MMNN and MM1 conditionsRouter Queue Simulation in C++ in MMNN and MM1 conditions
Router Queue Simulation in C++ in MMNN and MM1 conditions
Morteza Mahdilar
 
Cc code cards
Cc code cardsCc code cards
Cc code cards
ysolanki78
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
KAI CHU CHUNG
 
maXbox Starter 42 Multiprocessing Programming
maXbox Starter 42 Multiprocessing Programming maXbox Starter 42 Multiprocessing Programming
maXbox Starter 42 Multiprocessing Programming
Max Kleiner
 
Apache Flink @ NYC Flink Meetup
Apache Flink @ NYC Flink MeetupApache Flink @ NYC Flink Meetup
Apache Flink @ NYC Flink Meetup
Stephan Ewen
 
Streams
StreamsStreams
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
KAI CHU CHUNG
 
Flux and InfluxDB 2.0 by Paul Dix
Flux and InfluxDB 2.0 by Paul DixFlux and InfluxDB 2.0 by Paul Dix
Flux and InfluxDB 2.0 by Paul Dix
InfluxData
 
Pascal script maxbox_ekon_14_2
Pascal script maxbox_ekon_14_2Pascal script maxbox_ekon_14_2
Pascal script maxbox_ekon_14_2
Max Kleiner
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
JAXLondon_Conference
 

Similar to Go on! (20)

Web streams
Web streamsWeb streams
Web streams
 
Go Concurrency Patterns
Go Concurrency PatternsGo Concurrency Patterns
Go Concurrency Patterns
 
Writing a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdfWriting a TSDB from scratch_ performance optimizations.pdf
Writing a TSDB from scratch_ performance optimizations.pdf
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring framework
 
Async fun
Async funAsync fun
Async fun
 
Go and Uber’s time series database m3
Go and Uber’s time series database m3Go and Uber’s time series database m3
Go and Uber’s time series database m3
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
gRPC in Go
gRPC in GogRPC in Go
gRPC in Go
 
Pemrograman Python untuk Pemula
Pemrograman Python untuk PemulaPemrograman Python untuk Pemula
Pemrograman Python untuk Pemula
 
FreeRTOS
FreeRTOSFreeRTOS
FreeRTOS
 
Router Queue Simulation in C++ in MMNN and MM1 conditions
Router Queue Simulation in C++ in MMNN and MM1 conditionsRouter Queue Simulation in C++ in MMNN and MM1 conditions
Router Queue Simulation in C++ in MMNN and MM1 conditions
 
Cc code cards
Cc code cardsCc code cards
Cc code cards
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
 
maXbox Starter 42 Multiprocessing Programming
maXbox Starter 42 Multiprocessing Programming maXbox Starter 42 Multiprocessing Programming
maXbox Starter 42 Multiprocessing Programming
 
Apache Flink @ NYC Flink Meetup
Apache Flink @ NYC Flink MeetupApache Flink @ NYC Flink Meetup
Apache Flink @ NYC Flink Meetup
 
Streams
StreamsStreams
Streams
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
 
Flux and InfluxDB 2.0 by Paul Dix
Flux and InfluxDB 2.0 by Paul DixFlux and InfluxDB 2.0 by Paul Dix
Flux and InfluxDB 2.0 by Paul Dix
 
Pascal script maxbox_ekon_14_2
Pascal script maxbox_ekon_14_2Pascal script maxbox_ekon_14_2
Pascal script maxbox_ekon_14_2
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 

Recently uploaded

Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
brainerhub1
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
Hornet Dynamics
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
Sven Peters
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
kalichargn70th171
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdfRevolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
Undress Baby
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
mz5nrf0n
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
Gerardo Pardo-Castellote
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 

Recently uploaded (20)

Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf8 Best Automated Android App Testing Tool and Framework in 2024.pdf
8 Best Automated Android App Testing Tool and Framework in 2024.pdf
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdfRevolutionizing Visual Effects Mastering AI Face Swaps.pdf
Revolutionizing Visual Effects Mastering AI Face Swaps.pdf
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 

Go on!

  • 1. Go on! 3 June 2017 Vadim Petrov Software engineer, Juno
  • 2. Events collector The microservice receives events from mobile clients by HTTP, collects them in a batch of events and pass it to some 3rd-party system.
  • 4. Let's write some code All further code is real and runnable. You can nd it on GitHub. github.com/Barberrrry/go-on-presentation(https://github.com/Barberrrry/go-on-presentation)
  • 6. Fake processor Create fake processor with random processing time up to 200 ms. package processor type Batch []string type Fake struct{} func (f *Fake) Process(batch Batch) { if len(batch) == 0 { return } // Fake process time time.Sleep(time.Duration(rand.Intn(200)) * time.Millisecond) } That's enough for processor.
  • 8. Collector v1: naive plan Use a slice as a bu er Append incoming data to the bu er If bu er size reaches N, ush the bu er to Processor
  • 9. Collector v1: types package collector type Processor interface { Process(processor.Batch) } type Collector struct { Processor Processor MaxBatchSize int buffer processor.Batch }
  • 10. Collector v1: collect func (c *Collector) Collect(payload string) { c.buffer = append(c.buffer, payload) log.Printf("collected: %s", payload) if len(c.buffer) >= c.MaxBatchSize { c.flush(c.buffer) c.buffer = nil } } func (c *Collector) flush(batch processor.Batch) { t := time.Now() c.Processor.Process(batch) log.Printf("flushed %d payloads in %s", len(batch), time.Since(t)) }
  • 11. Collector v1: run func main() { collector := &collector.Collector{ Processor: &processor.Fake{}, MaxBatchSize: 2, } for i := 1; i <= 5; i++ { collector.Collect(fmt.Sprintf("event_%d", i)) } } Run
  • 12. Collector v1: conclusion Resolution: bad :( Problem: Function Collect() waits for Processor each N calls To be xed: Processor shouldn't block Collect() Let's make Collector concurrent.
  • 14. What is concurrency? Concurrency is the composition of independently executing computations. Concurrency is a way to design software. Concurrency is not parallelism, although it enables parallelism. Concurrency is about structure, parallelism is about execution. Go has rich support for concurrency using goroutines and channels.
  • 15. Goroutines Goroutine is an independently executing function, launched by a go statement. go func() { fmt.Println("Hi!") }() It's very cheap. It's practical to have thousands, even hundreds of thousands of goroutines. Gouroutine is not OS thread.
  • 16. Scheduler Scheduler runs N contexts. N is con gurable. It may be 1 context. Each context is running as OS thread. Each context has own queue of goroutines. Context stops goroutine execution on any blocking operation and starts next one from the queue.
  • 17. Communication Goroutines without any input or output are useless. Multiple goroutines require communication. Don't communicate by sharing memory, share memory by communicating. Instead of using locks to mediate access to shared data, use channels to pass data between goroutines.
  • 18. Channels A channel in Go provides a connection between two goroutines, allowing them to communicate. Channel values may have any type, even other channel. A channel is a blocking queue with de ned length.
  • 19. Channel bu er Bu ered channel c := make(chan string, 5) Unbu ered channel c := make(chan string)
  • 21. Collector v2: plan Implement worker Use channel to split incoming payloads among workers Worker has own bu er and ush it when ready Run several concurrent workers
  • 22. Collector v2: collector Add collector attributes and use channel as queue of incoming payloads. type ( Collector struct { Processor Processor MaxBatchSize int WorkersCount int QueueSize int payloadsQueue chan string } )
  • 23. Collector v2: worker Create worker() function with own bu er inside. Worker will ush bu er when it's ready. func (c *Collector) worker(id int) { var buffer processor.Batch log.Printf("worker_%d start", id) for payload := range c.payloadsQueue { buffer = append(buffer, payload) if len(buffer) >= c.MaxBatchSize { c.flush(id, buffer) buffer = nil } } }
  • 24. Collector v2: run workers Collect() just writes payload to queue. Create Run() function which will init queue channel and start N workers. func (c *Collector) Collect(payload string) { c.payloadsQueue <- payload log.Printf("collected: %s", payload) } func (c *Collector) Run() { log.Print("collector start") c.payloadsQueue = make(chan string, c.QueueSize) for i := 0; i < c.WorkersCount; i++ { go func(id int) { c.worker(id) }(i) } }
  • 25. Collector v2: run func main() { collector := &collector.Collector{ Processor: &processor.Fake{}, MaxBatchSize: 2, WorkersCount: 2, QueueSize: 1000, } collector.Run() for i := 1; i <= 5; i++ { collector.Collect(fmt.Sprintf("event_%d", i)) } time.Sleep(200 * time.Millisecond) } Run
  • 26. Collector v2: conclusion Resolution: better, but still not good Fixed: Function Collect() is not blocked anymore by Processor Workers are concurrent Problems: Bu er is ushed only when reaches max batch size To be xed: Flush bu er after some timeout since last ush
  • 28. Select The select statement waits on multiple communication operations. A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready. If all cases are not ready, default happens. values := make(chan int, 10) quit := make(chan struct{}) for { select { case v := <-values: fmt.Println(v) case <-quit: return default: time.Sleep(time.Second) } }
  • 30. Collector v3: plan Add ush interval as Collector parameter Force ush periodically
  • 31. Collector v3: collector Add ush interval as Collector parameter. type ( Collector struct { Processor Processor WorkersCount int MaxBatchSize int QueueSize int FlushInterval time.Duration payloadsQueue chan string } )
  • 32. Collector v3: ush timer func (c *Collector) worker(id int) { var buffer processor.Batch timer := time.NewTimer(c.FlushInterval) for { select { case payload := <-c.payloadsQueue: buffer = append(buffer, payload) if len(buffer) >= c.MaxBatchSize { c.flush(id, buffer, "size") buffer = nil timer.Reset(c.FlushInterval) } case <-timer.C: c.flush(id, buffer, "timer") buffer = nil timer.Reset(c.FlushInterval) } } }
  • 33. Collector v3: run func main() { collector := &collector.Collector{ Processor: &processor.Fake{}, MaxBatchSize: 2, WorkersCount: 2, QueueSize: 1000, FlushInterval: 200 * time.Millisecond, } collector.Run() for i := 1; i <= 5; i++ { time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) // Fake delay collector.Collect(fmt.Sprintf("event_%d", i)) } time.Sleep(300 * time.Millisecond) } Run
  • 36. HTTP handler Read HTTP request body and collect it by collector. func NewCollectorHandler(d *collector.Collector) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { payload, err := ioutil.ReadAll(req.Body) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } d.Collect(string(payload)) } }
  • 37. Start server func main() { collector := &collector.Collector{ Processor: &processor.Fake{}, MaxBatchSize: 5, WorkersCount: 3, QueueSize: 10000, FlushInterval: 5 * time.Second, } collector.Run() http.ListenAndServe("localhost:9090", server.NewCollectorHandler(collector)) }
  • 38. Go on! Let's run microservice and see how it works.
  • 39. Conclusions Go provides instruments to make complex things easy. Concurrent code enables runtime parallelism. Goroutines and channels are easy to use. But don't overuse these ideas. Always use the right tool for the job.
  • 40. Questions? This presentation slides and code: github.com/Barberrrry/go-on-presentation(https://github.com/Barberrrry/go-on-presentation) Concurrency in Go www.golang-book.com/books/intro/10(https://www.golang-book.com/books/intro/10) golang.org/doc/e ective_go.html#concurrency(https://golang.org/doc/e ective_go.html#concurrency) "Go Concurrency Patterns" by Rob Pike www.youtube.com/watch?v=f6kdp27TYZs(https://www.youtube.com/watch?v=f6kdp27TYZs) "Concurrency is not parallelism" by Rob Pike blog.golang.org/concurrency-is-not-parallelism(https://blog.golang.org/concurrency-is-not-parallelism)
  • 41. Thank you Vadim Petrov Software engineer, Juno vadim.petrov@gmail.com(mailto:vadim.petrov@gmail.com) https://www.facebook.com/barberry(https://www.facebook.com/barberry)