Every marginally, sophisticated Golang code that I write needs refactoring to solve race and deadlocks. The concurrency primitives like atomic, sync, channels, and waitGroups have their uses and fail. The lack of understanding ends up with a lot of rewrites. This talk aims to solve that.
I have seen more Go code shipped as glue programs and binaries than actual web servers, usually intended to do the heavy-lifting of data transfers shortly and reliably. With such clinical needs comes a need to handle concurrency and parallelism. And each time more than one worker is doing a job, there will be contention and starvation. A lack of useful design principle guides ends up in Engineers writing non-performant, race-condition prone codes or ending up refactoring.
To provide an example, some of the things I wish I had known:
The real difference of when to use a Channel, a waitGroup, an atomic, or a mutex – one shouldn’t be using a wg.Add() inside a goroutine.
How does one solve the problem of multiple listeners waiting on an event?
How atomic Int operations can synchronize multiple workers signaling completion of work.
The talk is not limited to the above scenarios. It intends to cover a few of these constructs to reduce the refactoring that Golang engineers have to go through while also building a better understanding of distributed systems’ design patterns.