SlideShare une entreprise Scribd logo
1  sur  37
Go Concurrency Patterns
By Vitalii Perehonchuk, Software Developer
www.eliftech.com
Let’s lets get through...
1. Projects not using concurrency
2. Atomic operations
3. Timeouts and tickers
4. Exit control
5. Event handling
6. Error handling
7. Tests and benchmarks
8. Something really interesting
www.eliftech.com
No concurrency in
▪ GoCV (computer vision)
▪ upper/db (drivers for MySQL,
PostgreSQL, SQLite, MongoDB,
etc)
▪ goquery (jQuery port)
▪ authboss (Auth library)
▪ go-jose (JS-way data signing and
encryption library)
▪ go-oauth2-server
▪ goth (Multi-provider auth library)
▪ oauth2 (OAuth2 library)
▪ docopt-go (Toolset for pretty CLI)
▪ go-flags (CLI options parser)
▪ kingpin (CLI library)
▪ urfave/cli (CLI library)
▪ asciigraph (lightweight ASCII line
graphs in CLI)
▪ go-prompt (CLI library)
▪ godotenv (.env library)
▪ ini (.ini library)
▪ gods (Go data structures)
▪ ...
www.eliftech.com
Atomic operations
www.eliftech.com
Cockroach - scalable & transactional datastore
Uuid generator
// Returns the epoch and clock sequence.
func (g *Gen) getClockSequence() (uint64, uint16, error) {
g.clockSequenceOnce.Do(func() {
buf := make([]byte, 2)
io.ReadFull(g.rand, buf)
g.clockSequence = binary.BigEndian.Uint16(buf)
})
...
www.eliftech.com
goleveldb - fast key-value storage library
type memdbReleaser struct {
once sync.Once
m *memDB
}
func (mr *memdbReleaser) Release() {
mr.once.Do(func() {
mr.m.decref()
})
}
www.eliftech.com
Groupcache - cache library
// An AtomicInt is an int64 to be accessed atomically.
type AtomicInt int64
func (i *AtomicInt) Add(n int64) {
atomic.AddInt64((*int64)(i), n)
}
func (i *AtomicInt) Get() int64 {
return atomic.LoadInt64((*int64)(i))
}
func (i *AtomicInt) String() string {
return strconv.FormatInt(i.Get(), 10)
}
www.eliftech.com
Tickers and timeouts
www.eliftech.com
tebeka/selenium - WebDriver client for Go
go func() {
bufr := bufio.NewReader(r)
s, err :=
bufr.ReadString('n')
ch <- resp{s, err}
}()
var display string
select {
case resp := <-ch:
if resp.err != nil {
return nil,
resp.err
}
display =
strings.TrimSpace(resp.display)
case <-time.After(3 * time.Second):
return nil,
errors.New("timeout waiting for
Xvfb")
}
www.eliftech.com
minimp3 - lightweight MP3 decoder library
// Started check the record mp3 stream started or not.
func (dec *Decoder) Started() (channel chan bool) {
channel = make(chan bool)
go func() {
for {
select {
case <-dec.context.Done():
channel <- false
default:
}
...
www.eliftech.com
minimp3 - lightweight MP3 decoder library
...
if len(dec.decodedData) != 0 {
channel <- true
} else {
<-time.After(time.Millisecond *
100)
}
}
}()
return channel
}
www.eliftech.com
casbin - auth library with access control models support
func (e *SyncedEnforcer) StartAutoLoadPolicy(d time.Duration) {
e.autoLoad = true
go func() {
n := 1
for {
if !e.autoLoad { break }
e.LoadPolicy()
n++
time.Sleep(d)
}
}()
}
www.eliftech.com
minimp3 - lightweight MP3 decoder library
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for range ticker.C {
if atomic.LoadInt32(&stopAll) > 0 {
return
}
if time.Now().After(endTs) {
return
}
}
www.eliftech.com
rqlite - lightweight relational database with SQLite storage
// checkConnections periodically checks which connections should
close due to timeouts.
func (s *Store) checkConnections() {
s.wg.Add(1)
ticker := time.NewTicker(s.connPollPeriod)
go func() {
defer s.wg.Done()
defer ticker.Stop()
for {
select {
case <-s.done: return
case <-ticker.C:
...
www.eliftech.com
BigCache - efficient key-value store for gigabytes
ticker := time.NewTicker(config.CleanWindow)
defer ticker.Stop()
for {
select {
case t := <-ticker.C:
cache.cleanUp(uint64(t.Unix()))
case <-cache.close:
return
}
}
www.eliftech.com
Exit control
www.eliftech.com
telegram-bot-api - Telegram bot client
// GetUpdatesChan starts and returns a channel for getting updates.
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig)
(UpdatesChannel, error) {
ch := make(chan Update, bot.Buffer)
go func() {
for {
select {
case <-bot.shutdownChannel: return
default:
}
updates, err := bot.GetUpdates(config)
...
www.eliftech.com
telegram-bot-api - Telegram bot client
...
if err != nil {
time.Sleep(time.Second * 3)
continue
}
for _, update := range updates {
if update.UpdateID >= config.Offset
{
config.Offset =
update.UpdateID + 1
ch <- update
}
}}}()
return ch, nil
}
www.eliftech.com
Drone - CI platform built on Docker
import "golang.org/x/sync/errgroup"
var g errgroup.Group
g.Go(func() error {
return s1.ListenAndServe()
})
g.Go(func() error {
return
s2.ListenAndServeTLS(
s.Cert,
s.Key,
)
})
g.Go(func() error {
select {
case <-ctx.Done():
s1.Shutdown(ctx)
s2.Shutdown(ctx)
return nil
}
})
g.Wait()
www.eliftech.com
Event handling
www.eliftech.com
rakyll/portmidi - Go bindings for PortMidi
// Listen input stream for MIDI events.
func (s *Stream) Listen() <-chan Event {
ch := make(chan Event)
go func(s *Stream, ch chan Event) {
for {
// sleep for a while before the new polling
tick,
// otherwise operation is too intensive and
blocking
time.Sleep(10 * time.Millisecond)
events, err := s.Read(1024)
// Note: It's not very reasonable to push sliced data
into
// a channel, several perf penalties there
are.
// This function is added as a handy utility.
if err != nil { continue }
for i := range events { ch <- events[i] }
}
}(s, ch)
return ch
www.eliftech.com
gocui - minimalist library for CLI
go func() {
g.tbEvents <- termbox.Event{
Type: termbox.EventResize,
}
}()
for {
select {
case ev := <-g.tbEvents:
g.handleEvent(&ev)
case ev := <-g.userEvents:
ev.f(g)
}
g.consumeevents()
g.flush()
}
www.eliftech.com
Error handling
www.eliftech.com
dgraph - graph database
...
che := make(chan error, 1)
chb := make(chan []byte, 1000)
go func() {
che <- writeToFile(output, chb)
}()
…
return che
www.eliftech.com
Tests and benchmarks
www.eliftech.com
`go test` command runs tests in goroutines,
thus - concurrently, but not parallelly by default.
Having run `t.Parallel()` within its code, a test is run parallelly with another parallel tests (but
never - with other runs of itself).
www.eliftech.com
Many libraries use goroutines only in tests and examples - to test itselves against race
conditions.
www.eliftech.com
goleveldb - fast key-value storage library
b.SetParallelism(10)
b.RunParallel(func(pb *testing.PB) {
…
})
www.eliftech.com
TiDB - distributed HTAP database
// batchRW makes sure conflict free.
func batchRW(value []byte) {
wg := sync.WaitGroup{}
wg.Add(*workerCnt)
for i := 0; i < *workerCnt; i++ {
go func(i int) {
defer wg.Done()
…
}(i)
}
wg.Wait()
}
www.eliftech.com
1 million requests per
minute?..
www.eliftech.com
Malwarebytes
type Dispatcher struct {
// A pool of workers channels that are registered with the
dispatcher
WorkerPool chan chan Job
}
func NewDispatcher(maxWorkers int) *Dispatcher {
pool := make(chan chan Job, maxWorkers)
return &Dispatcher{WorkerPool: pool}
}
...
www.eliftech.com
Malwarebytes
...
func (d *Dispatcher) Run() {
// starting n number of workers
for i := 0; i < d.maxWorkers; i++ {
worker := NewWorker(d.pool)
worker.Start()
}
go d.dispatch()
}
...
www.eliftech.com
Malwarebytes
...
func (d *Dispatcher) dispatch() {
for {
select {
case job := <-JobQueue:
// a job request has been received
go func(job Job) {
// try to obtain a worker job channel
that is available.
// this will block until a worker is
idle
jobChannel := <-d.WorkerPool
// dispatch the job to the worker job
channel
jobChannel <- job
}(job)
}
}
}
www.eliftech.com
Malwarebytes
// Start method starts the run loop for the worker, listening for a quit
channel in
// case we need to stop it
func (w Worker) Start() {
go func() {
for {
// register the current worker into the worker
queue.
w.WorkerPool <- w.JobChannel
select {
case job := <-w.JobChannel:
// we have received a work request.
job.Payload.UploadToS3()
case <-w.quit:
return // we have received a signal to
stop
}
}
}()
}
www.eliftech.com
Conclusion
Concurrency and parallelism are widely used by Open
Source projects in Go.
Concurrency and parallelism are NOT used by many Open
Source projects in Go.
Parallel testing and benchmarking is a common practice.
www.eliftech.com
Sources
1. github.com
2. gopkg.in
3. godoc.org
4. golang.org
5. “Handling 1 Million Requests per Minute with Go“ by Marcio Castilho
www.eliftech.com
Don't forget to subscribe not to
miss our next presentations!
Find us at eliftech.com
Have a question? Contact us:
info@eliftech.com

Contenu connexe

Tendances

20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting Started20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting Started
Teerawat Issariyakul
 
jimmy hacking (at) Microsoft
jimmy hacking (at) Microsoftjimmy hacking (at) Microsoft
jimmy hacking (at) Microsoft
Jimmy Schementi
 

Tendances (20)

R/C++ talk at earl 2014
R/C++ talk at earl 2014R/C++ talk at earl 2014
R/C++ talk at earl 2014
 
Lua: the world's most infuriating language
Lua: the world's most infuriating languageLua: the world's most infuriating language
Lua: the world's most infuriating language
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in go
 
HAB Software Woes
HAB Software WoesHAB Software Woes
HAB Software Woes
 
20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting Started20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting Started
 
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
 
Rcpp11
Rcpp11Rcpp11
Rcpp11
 
NS2 Object Construction
NS2 Object ConstructionNS2 Object Construction
NS2 Object Construction
 
Coroutines in Kotlin
Coroutines in KotlinCoroutines in Kotlin
Coroutines in Kotlin
 
Object Detection with Tensorflow
Object Detection with TensorflowObject Detection with Tensorflow
Object Detection with Tensorflow
 
Clojure+ClojureScript Webapps
Clojure+ClojureScript WebappsClojure+ClojureScript Webapps
Clojure+ClojureScript Webapps
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 
Troubleshooting .net core on linux
Troubleshooting .net core on linuxTroubleshooting .net core on linux
Troubleshooting .net core on linux
 
Functional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptFunctional Reactive Programming in Clojurescript
Functional Reactive Programming in Clojurescript
 
Lecture 5, c++(complete reference,herbet sheidt)chapter-15
Lecture 5, c++(complete reference,herbet sheidt)chapter-15Lecture 5, c++(complete reference,herbet sheidt)chapter-15
Lecture 5, c++(complete reference,herbet sheidt)chapter-15
 
jimmy hacking (at) Microsoft
jimmy hacking (at) Microsoftjimmy hacking (at) Microsoft
jimmy hacking (at) Microsoft
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
Concurrency with Go
Concurrency with GoConcurrency with Go
Concurrency with Go
 
Full Stack Clojure
Full Stack ClojureFull Stack Clojure
Full Stack Clojure
 
ClojureScript for the web
ClojureScript for the webClojureScript for the web
ClojureScript for the web
 

Similaire à Go Concurrency Patterns

Lego: A brick system build by scala
Lego: A brick system build by scalaLego: A brick system build by scala
Lego: A brick system build by scala
lunfu zhong
 
Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrency
Cloudflare
 

Similaire à Go Concurrency Patterns (20)

Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio module
 
How to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking NeedsHow to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking Needs
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in Golang
 
Async programming and python
Async programming and pythonAsync programming and python
Async programming and python
 
Python, do you even async?
Python, do you even async?Python, do you even async?
Python, do you even async?
 
Lego: A brick system build by scala
Lego: A brick system build by scalaLego: A brick system build by scala
Lego: A brick system build by scala
 
Ad Server Optimization
Ad Server OptimizationAd Server Optimization
Ad Server Optimization
 
Writing Docker monitoring agent with Go
Writing Docker monitoring agent with GoWriting Docker monitoring agent with Go
Writing Docker monitoring agent with Go
 
Go on!
Go on!Go on!
Go on!
 
Original slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talkOriginal slides from Ryan Dahl's NodeJs intro talk
Original slides from Ryan Dahl's NodeJs intro talk
 
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
 
Reactive server with netty
Reactive server with nettyReactive server with netty
Reactive server with netty
 
Pharos
PharosPharos
Pharos
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0
 
От Java Threads к лямбдам, Андрей Родионов
От Java Threads к лямбдам, Андрей РодионовОт Java Threads к лямбдам, Андрей Родионов
От Java Threads к лямбдам, Андрей Родионов
 
History of asynchronous in .NET
History of asynchronous in .NETHistory of asynchronous in .NET
History of asynchronous in .NET
 
От Java Threads к лямбдам, Андрей Родионов
От Java Threads к лямбдам, Андрей РодионовОт Java Threads к лямбдам, Андрей Родионов
От Java Threads к лямбдам, Андрей Родионов
 
Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrency
 

Plus de ElifTech

Plus de ElifTech (20)

Domain Logic Patterns
Domain Logic PatternsDomain Logic Patterns
Domain Logic Patterns
 
Dive into .Net Core framework
Dive into .Net Core framework Dive into .Net Core framework
Dive into .Net Core framework
 
VR digest. August 2018
VR digest. August 2018VR digest. August 2018
VR digest. August 2018
 
JS digest. July 2018
JS digest.  July 2018JS digest.  July 2018
JS digest. July 2018
 
VR digest. July 2018
VR digest. July 2018VR digest. July 2018
VR digest. July 2018
 
IoT digest. July 2018
IoT digest. July 2018IoT digest. July 2018
IoT digest. July 2018
 
VR digest. June 2018
VR digest. June 2018VR digest. June 2018
VR digest. June 2018
 
IoT digest. June 2018
IoT digest. June 2018IoT digest. June 2018
IoT digest. June 2018
 
IoT digest. May 2018
IoT digest. May 2018IoT digest. May 2018
IoT digest. May 2018
 
VR digest. May 2018
VR digest. May 2018VR digest. May 2018
VR digest. May 2018
 
Polymer: brief introduction
Polymer: brief introduction Polymer: brief introduction
Polymer: brief introduction
 
JS digest. April 2018
JS digest. April 2018JS digest. April 2018
JS digest. April 2018
 
VR digest. April, 2018
VR digest. April, 2018 VR digest. April, 2018
VR digest. April, 2018
 
IoT digest. April 2018
IoT digest. April 2018IoT digest. April 2018
IoT digest. April 2018
 
IoT digest. March 2018
IoT digest. March 2018IoT digest. March 2018
IoT digest. March 2018
 
VR digest. March, 2018
VR digest. March, 2018VR digest. March, 2018
VR digest. March, 2018
 
VR digest. February, 2018
VR digest. February, 2018VR digest. February, 2018
VR digest. February, 2018
 
IoT digest. February 2018
IoT digest. February 2018IoT digest. February 2018
IoT digest. February 2018
 
JS digest. January 2018
JS digest. January 2018 JS digest. January 2018
JS digest. January 2018
 
VR digest. January 2018
VR digest. January 2018VR digest. January 2018
VR digest. January 2018
 

Dernier

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 

Dernier (20)

W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 

Go Concurrency Patterns

  • 1. Go Concurrency Patterns By Vitalii Perehonchuk, Software Developer
  • 2. www.eliftech.com Let’s lets get through... 1. Projects not using concurrency 2. Atomic operations 3. Timeouts and tickers 4. Exit control 5. Event handling 6. Error handling 7. Tests and benchmarks 8. Something really interesting
  • 3. www.eliftech.com No concurrency in ▪ GoCV (computer vision) ▪ upper/db (drivers for MySQL, PostgreSQL, SQLite, MongoDB, etc) ▪ goquery (jQuery port) ▪ authboss (Auth library) ▪ go-jose (JS-way data signing and encryption library) ▪ go-oauth2-server ▪ goth (Multi-provider auth library) ▪ oauth2 (OAuth2 library) ▪ docopt-go (Toolset for pretty CLI) ▪ go-flags (CLI options parser) ▪ kingpin (CLI library) ▪ urfave/cli (CLI library) ▪ asciigraph (lightweight ASCII line graphs in CLI) ▪ go-prompt (CLI library) ▪ godotenv (.env library) ▪ ini (.ini library) ▪ gods (Go data structures) ▪ ...
  • 5. www.eliftech.com Cockroach - scalable & transactional datastore Uuid generator // Returns the epoch and clock sequence. func (g *Gen) getClockSequence() (uint64, uint16, error) { g.clockSequenceOnce.Do(func() { buf := make([]byte, 2) io.ReadFull(g.rand, buf) g.clockSequence = binary.BigEndian.Uint16(buf) }) ...
  • 6. www.eliftech.com goleveldb - fast key-value storage library type memdbReleaser struct { once sync.Once m *memDB } func (mr *memdbReleaser) Release() { mr.once.Do(func() { mr.m.decref() }) }
  • 7. www.eliftech.com Groupcache - cache library // An AtomicInt is an int64 to be accessed atomically. type AtomicInt int64 func (i *AtomicInt) Add(n int64) { atomic.AddInt64((*int64)(i), n) } func (i *AtomicInt) Get() int64 { return atomic.LoadInt64((*int64)(i)) } func (i *AtomicInt) String() string { return strconv.FormatInt(i.Get(), 10) }
  • 9. www.eliftech.com tebeka/selenium - WebDriver client for Go go func() { bufr := bufio.NewReader(r) s, err := bufr.ReadString('n') ch <- resp{s, err} }() var display string select { case resp := <-ch: if resp.err != nil { return nil, resp.err } display = strings.TrimSpace(resp.display) case <-time.After(3 * time.Second): return nil, errors.New("timeout waiting for Xvfb") }
  • 10. www.eliftech.com minimp3 - lightweight MP3 decoder library // Started check the record mp3 stream started or not. func (dec *Decoder) Started() (channel chan bool) { channel = make(chan bool) go func() { for { select { case <-dec.context.Done(): channel <- false default: } ...
  • 11. www.eliftech.com minimp3 - lightweight MP3 decoder library ... if len(dec.decodedData) != 0 { channel <- true } else { <-time.After(time.Millisecond * 100) } } }() return channel }
  • 12. www.eliftech.com casbin - auth library with access control models support func (e *SyncedEnforcer) StartAutoLoadPolicy(d time.Duration) { e.autoLoad = true go func() { n := 1 for { if !e.autoLoad { break } e.LoadPolicy() n++ time.Sleep(d) } }() }
  • 13. www.eliftech.com minimp3 - lightweight MP3 decoder library ticker := time.NewTicker(time.Second) defer ticker.Stop() for range ticker.C { if atomic.LoadInt32(&stopAll) > 0 { return } if time.Now().After(endTs) { return } }
  • 14. www.eliftech.com rqlite - lightweight relational database with SQLite storage // checkConnections periodically checks which connections should close due to timeouts. func (s *Store) checkConnections() { s.wg.Add(1) ticker := time.NewTicker(s.connPollPeriod) go func() { defer s.wg.Done() defer ticker.Stop() for { select { case <-s.done: return case <-ticker.C: ...
  • 15. www.eliftech.com BigCache - efficient key-value store for gigabytes ticker := time.NewTicker(config.CleanWindow) defer ticker.Stop() for { select { case t := <-ticker.C: cache.cleanUp(uint64(t.Unix())) case <-cache.close: return } }
  • 17. www.eliftech.com telegram-bot-api - Telegram bot client // GetUpdatesChan starts and returns a channel for getting updates. func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) (UpdatesChannel, error) { ch := make(chan Update, bot.Buffer) go func() { for { select { case <-bot.shutdownChannel: return default: } updates, err := bot.GetUpdates(config) ...
  • 18. www.eliftech.com telegram-bot-api - Telegram bot client ... if err != nil { time.Sleep(time.Second * 3) continue } for _, update := range updates { if update.UpdateID >= config.Offset { config.Offset = update.UpdateID + 1 ch <- update } }}}() return ch, nil }
  • 19. www.eliftech.com Drone - CI platform built on Docker import "golang.org/x/sync/errgroup" var g errgroup.Group g.Go(func() error { return s1.ListenAndServe() }) g.Go(func() error { return s2.ListenAndServeTLS( s.Cert, s.Key, ) }) g.Go(func() error { select { case <-ctx.Done(): s1.Shutdown(ctx) s2.Shutdown(ctx) return nil } }) g.Wait()
  • 21. www.eliftech.com rakyll/portmidi - Go bindings for PortMidi // Listen input stream for MIDI events. func (s *Stream) Listen() <-chan Event { ch := make(chan Event) go func(s *Stream, ch chan Event) { for { // sleep for a while before the new polling tick, // otherwise operation is too intensive and blocking time.Sleep(10 * time.Millisecond) events, err := s.Read(1024) // Note: It's not very reasonable to push sliced data into // a channel, several perf penalties there are. // This function is added as a handy utility. if err != nil { continue } for i := range events { ch <- events[i] } } }(s, ch) return ch
  • 22. www.eliftech.com gocui - minimalist library for CLI go func() { g.tbEvents <- termbox.Event{ Type: termbox.EventResize, } }() for { select { case ev := <-g.tbEvents: g.handleEvent(&ev) case ev := <-g.userEvents: ev.f(g) } g.consumeevents() g.flush() }
  • 24. www.eliftech.com dgraph - graph database ... che := make(chan error, 1) chb := make(chan []byte, 1000) go func() { che <- writeToFile(output, chb) }() … return che
  • 26. www.eliftech.com `go test` command runs tests in goroutines, thus - concurrently, but not parallelly by default. Having run `t.Parallel()` within its code, a test is run parallelly with another parallel tests (but never - with other runs of itself).
  • 27. www.eliftech.com Many libraries use goroutines only in tests and examples - to test itselves against race conditions.
  • 28. www.eliftech.com goleveldb - fast key-value storage library b.SetParallelism(10) b.RunParallel(func(pb *testing.PB) { … })
  • 29. www.eliftech.com TiDB - distributed HTAP database // batchRW makes sure conflict free. func batchRW(value []byte) { wg := sync.WaitGroup{} wg.Add(*workerCnt) for i := 0; i < *workerCnt; i++ { go func(i int) { defer wg.Done() … }(i) } wg.Wait() }
  • 31. www.eliftech.com Malwarebytes type Dispatcher struct { // A pool of workers channels that are registered with the dispatcher WorkerPool chan chan Job } func NewDispatcher(maxWorkers int) *Dispatcher { pool := make(chan chan Job, maxWorkers) return &Dispatcher{WorkerPool: pool} } ...
  • 32. www.eliftech.com Malwarebytes ... func (d *Dispatcher) Run() { // starting n number of workers for i := 0; i < d.maxWorkers; i++ { worker := NewWorker(d.pool) worker.Start() } go d.dispatch() } ...
  • 33. www.eliftech.com Malwarebytes ... func (d *Dispatcher) dispatch() { for { select { case job := <-JobQueue: // a job request has been received go func(job Job) { // try to obtain a worker job channel that is available. // this will block until a worker is idle jobChannel := <-d.WorkerPool // dispatch the job to the worker job channel jobChannel <- job }(job) } } }
  • 34. www.eliftech.com Malwarebytes // Start method starts the run loop for the worker, listening for a quit channel in // case we need to stop it func (w Worker) Start() { go func() { for { // register the current worker into the worker queue. w.WorkerPool <- w.JobChannel select { case job := <-w.JobChannel: // we have received a work request. job.Payload.UploadToS3() case <-w.quit: return // we have received a signal to stop } } }() }
  • 35. www.eliftech.com Conclusion Concurrency and parallelism are widely used by Open Source projects in Go. Concurrency and parallelism are NOT used by many Open Source projects in Go. Parallel testing and benchmarking is a common practice.
  • 36. www.eliftech.com Sources 1. github.com 2. gopkg.in 3. godoc.org 4. golang.org 5. “Handling 1 Million Requests per Minute with Go“ by Marcio Castilho
  • 37. www.eliftech.com Don't forget to subscribe not to miss our next presentations! Find us at eliftech.com Have a question? Contact us: info@eliftech.com