Go Channel Patterns  - Fan Out
Tags: go, beginners, programming, tutorial
Published: 2021-12-12 21:35:44

---
series: [Go Channel Patterns]
---

To improve my Go Programming skills and become a better Go engineer, I have recently purchased an excellent on-demand education from [Ardan Labs](https://www.ardanlabs.com/education/). Materials are created by an expert Go engineer, [Bill Kennedy](https://twitter.com/goinggodotnet).

{% twitter 1455534157275205640 %}


I have decide to record my process of learning how to write more idiomatic code, following Go best practices and design philosophies. 

This series of posts will describe channel patterns used for orchestration/signaling in Go via goroutines.

## Fan Out Pattern

The main idea behind **Fan Out Pattern** is to have:
- a channel that provides a signaling semantics
  - channel can be buffered, so we don't wait on immediate receive confirmation
- a goroutine that starts multiple (other) goroutines to do some work
- a multiple goroutines that do some work and use signaling channel to signal that the work is done

![Fan Out Pattern](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75veyea6p6vynzpc3zse.png)

### Example

In this example we have multiple `employees` that have some work to do. We also have a `manager` (`main` goroutine) that waits on that work to be done. Once each `employee` work is done, `employee` notifies `manager` by sending a signal (`paper`) via communication channel `ch`. 

Feel free to try the example on [Go Playground](https://play.golang.com/p/Y8xdoNBhrrK)

```go
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {

	employees := 3

	// make channel of type string which provides signaling semantics
	// buffered channel is used so no goroutine blocks a sending operation
	// if two goroutines send a signal at the same time, channel performs synchronization
	ch := make(chan string, employees)

	for e := 0; e < employees; e++ {

		// start goroutine that does some work for employee e
		go func(employee int) {

			// simulate the idea of unknown latency (do not use in production)
			time.Sleep(time.Duration(rand.Intn(200)) * time.Millisecond)
                        // when work is done send signal
			ch <- "paper"
			fmt.Println("employee : sent signal :", employee)
		}(e)
	}

	// goroutine 'main' => manager
	// goroutines 'main' and employee goroutines are executed in parallel

	// wait for all employee work to be done
	for employees > 0 {
		// receive signal sent from the employee
		p := <-ch

		employees--
		fmt.Println(p)
		fmt.Println("manager : received signal :", p)
	}

	time.Sleep(time.Second)
}

```

### Result
```sh
go run main.go

employee : sent signal : 1
paper
manager : received signal : paper
employee : sent signal : 2
paper
manager : received signal : paper
employee : sent signal : 0
paper
manager : received signal : paper
```


## Conclusion
In this article, fan out channel pattern was described. In addition, simple implementation was provided.

Readers are encouraged to check out excellent [Ardan Labs](https://www.ardanlabs.com/education/) education materials to learn more.

Resources:
1. [Ardan Labs](https://www.ardanlabs.com/)
2. [Cover image by Igor Mashkov from Pexels](https://www.pexels.com/photo/radio-telescope-against-sky-with-stars-6325001/)
3. [Fan out picture](https://habr.com/ru/company/ua-hosting/blog/490750/)