Fan-in Multiplexing Pattern Explained With Golang - A fastest horse analogy.
Introduction
In computer science, multiplexing is a system or signal involving simultaneous transmission of several messages along a single channel of communication.
Conveniently, we'd be writing the solution in Go and utilising go's channels for our analogy's code implementation. Hence, at the end of this post, I would use a world case to explain an implementation of Multiplexing with the Fan-in pattern. We'd also get to see what a generator function is.
Analogy
Today, we'll be considering a horse racing event. A horse race consists of multiple horses and you being the reader is charged as the officiating officer for the event. Unbeknownst to the event organisers, you're a 10x developer. 💪🏽.
Prior to the event, you decided to visit the venue to check things out. During your visit, you started playing the possible scenarios that can make your task difficult.
Firstly, you wonder how you'll efficiently tell the fastest horse as you're equipped with eyes that focus on one thing at a time. You wonder how you're to focus on the horses since multitasking is not something we humans have in our design.
One of the solutions you came up with as a 10x developer is to make the horses tell you when they cross the finish line. Borrowing from the earlier definition of multiplexing, the horses will be making simultaneous transmissions of their finish times to your ears. Your ear is the hypothetical single channel of communication. And when they have all sent their finish times to you, you can then decide the winner as the horse that took the least amount of time to complete the race.
Code Solution
We'll first start by identifying the number of horses that would run. For our example, we'd be working with the following five horses: Gem, Frank, Lilly, Arnold, and Ola.
Consider the track()
function below. Every horse will be passed to the track()
function and for simplicity case, the track()
function will simulate the race time for a horse and then pass the horse name and race completion time to the output channel.
func track(name string) <-chan string {
c := make(chan string)
go func() {
// Simulate random race time for a horse
d := time.Duration(rand.Intn(1e2)) * time.Millisecond
time.Sleep(d)
// End simulation
c <- fmt.Sprintf("%s %d%s", name, d/1e6, "ms")
}()
return c
}
Tip : 1e6 is equivalent to one multiplied by ten to the power of six (i.e 1 * 10⁶)
The
track()
function above is example of a generator function implementation. It generates the data that tells us of the time taken for a horse to finish a race.
We'd now need to track all the horses simultaneously and we'd do this by fanning in all the track()
responses for the horses in the race. Consider the fanInHorse()
function below.
func RaceHorses() {
// seed to enable proper random race time generation per horse
rand.Seed(time.Now().UTC().UnixNano())
fmt.Println(" - Race starts. - \n ")
c := fanInHorse(track("Gem"), track("Frank"), track("Lilly"), track("Arnold"), track("Ola"))
.
.
.
}
func fanInHorse(hn …<-chan string) <-chan string {
c := make(chan string)
for _, v := range hn {
go func(i <-chan string) {
c <- <-i
}(v)
}
return c
}
fanInHorse()
function will take all the track()
responses and pass them to a single channel. This is synonymous with our eye observation as we're now looking at only one channel instead of observing five channels.
The complete version of RaceHorses()
below adds how we print the output of the channel in the order they came in, that is, first in first out.
func RaceHorses() {
// seed to enable proper random race time generation per horse
rand.Seed(time.Now().UTC().UnixNano())
fmt.Println(" - Race starts. - \n ")
c := fanInHorse(track("Gem"), track("Frank"), track("Lilly"), track("Arnold"), track("Ola"))
for i := 0; i < 5; i++ {
fmt.Printf("%s \n", <-c)
}
fmt.Println("\n - Race ends. - ")
}
A sample response of the RaceHorses()
is given below. From the sample Frank is the fastest horse.
-- Race starts. --
Frank 34ms
Ola 47ms
Gem 47ms
Arnold 57ms
Lilly 98ms
-- Race ends. --
Summary
With this, you've implemented a Fan-in Multiplexing pattern and seen examples of generator functions.
You can also get the full source code from this gist
If this teaching technique was useful, you can share it across your social media accounts for your friends or get in touch by visiting my website.
Happy coding. Cheers.