Concurrency Patterns: Golang
While my previous article covered the basics of Concurrency in Golang, this article will shed light on some of the Concurrency Patterns followed in the world of Go.
Generator aka Iterator
Generator Pattern is used to generate a sequence of values which is used to produce some output. This pattern is widely used to introduce parallelism into loops. This allows the consumer of the data produced by the generator to run in parallel when the generator function is busy computing the next value.
Generators in Go are implemented with goroutines. The fib function passes the Fibonacci number with the help of channels, which is then consumed in the loop to generate output. The generator and the consumer can work concurrently (maybe in parallel) as the logic involved in both are different.
A Future indicates any data that is needed in future but its computation can be started in parallel so that it can be fetched from the background when needed. The Future/Promise pattern is implemented in many languages. For example, JQuery implements a deferred object and futures are built into Scala. In the land of Golang, the goroutine and channel concurrency primitives can be used to build up the functionality.
Mostly, futures are used to send asynchronous http request.
The actual http request is done asynchronously in a goroutine. The main function can continue doing other things. When the result is needed, we read the result from the channel. If the request isn’t finished yet, the channel will block until the result is ready. The unit test for futureData is shown below
Fan-in Fan-out is a way of Multiplexing and Demultiplexing in golang. Fan-in refers to processing multiple input data and combining into a single entity. Fan-out is the exact opposite, dividing the data into multiple smaller chunks, distributing the work amongst a group of workers to parallelize CPU use and I/O.
Each instance of the squareNumber function reads from the same input channel until that channel is closed. The fanin function can read from multiple inputs channels and proceed until all are closed by multiplexing the input channels onto a single channel that’s closed when all the inputs are closed.