How would you organize your goroutine and channel? (P1)

P1 TLDR: keep the state in the message! and if you don’t know what that means yet, keep reading.
P2: Complex routing with channel and goroutine.

Image for post
Image for post

Goroutine and channel are the embraced model to do concurrency in Go. Channel syntax abstracts the explicit use of locks and help developer avoid incorrect data flow.

This post will focus on how to organize them into composable and reusable code.

Simplest: Fire-and-forget (only apply for async ops with no result collecting). Very easy but don’t forget to set your timer (especially on i/o call)

Great… Wait, we don’t need that closure do we:

Much brevity but DON’T do the above in a loop with different arguments, you will need function scope, this is best for writing some scripts to get the job done.

Intermediate: Long running goroutines listen to a channel, they all do the same logic - process data and send back result (you may call them workers pool).

Great… Wait do we really need 3 channels? error in Go is just value, we can combine error and result together and reduce it to 2 channels, in and out!

Another intermediate: Long running goroutines listen on multiple channels. Given scenario that a set of workers listen to 2 or more channels to do different kind of work. This is particular common in a lot of codebase, so I think it’s beneficial to point it out.

Great… Wait that’s 4 channels already, only for 2 types of work! and quite a pattern of repetitive code, imagine we have to do this with 3, 4 or even 10 types of work (we will need 2x number of channels!)

Channel is just a medium for communication between goroutines. A good medium is a stateless one, it shouldn’t care what it carries. To reduce the number of channels (down to a fixed 2 - in and out!) disregarding how many types of work, we can do this:

or even better, consider in and out data types are just data!

The only notice is that we should increase the buffer if the message carry more types, for above example, we can bump the buffer up to guarantee the same throughput (in ideal scenario):

For complex message routing, please see P2 here.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store