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
}
}
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()
}
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).
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}
}
...
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.
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