S1E2: Mastering the Concurrency in Go with Boring Desing Pattern
In this series we have already learned: (Concurrency Design Patterns — YouTube)
- S1E1: Concurrency In Go | Goroutine | Channels | Waitgroup | Buffered Channel | by Arshlan | Jul, 2023 | Medium
- S1E2: Concurrency Boring Desing Pattern in Go | by Arshlan | Jul, 2023 | Medium
- S1E3: Mastering Concurrency with Worker Pool in GoLang: A Scalable Solution for Efficient Task Processing | by Arshlan | Aug, 2023 | Medium
- S1E4: Mastering Concurrency Fan-In Design Pattern | by Arshlan | Aug, 2023 | Medium
- S1E5: Mastering the Concurrency in Go with Fan Out Design Pattern | by Arshlan | Aug, 2023 | Medium
Today we will continue our Concurrency Design Pattern web series, in this blog we will learn about the Boring Design Pattern. If you want to keep update with the latest video, then please subscribe my YouTube channel.
For full explanation: S1E2: Boring Design Pattern | Concurrency Design Pattern Series | Go Lang | Goroutine + Waitgroups — YouTube
Previous Blog on the Basics of concurrency: S1E1: Concurrency In Go | Goroutine | Channels | Waitgroup | Buffered Channel | by Arshlan | Jul, 2023 | Medium
Let’s first see where we can apply this pattern and what can be the use cases of this pattern:
- Small and Independent Tasks: The boring design pattern is well-suited for scenarios where you have several small and independent tasks that can be executed concurrently. Each task can be encapsulated within a separate goroutine.
- I/O-Bound Operations: For applications that involve I/O-bound operations (e.g., reading and writing to files, making network requests), the boring design pattern can be beneficial. Concurrently executing I/O-bound tasks using goroutines and channels can improve overall throughput and performance.
- Event Handling: When dealing with events or event-driven programming, the boring design pattern can be employed to handle multiple events concurrently. Each event handler can run in its own goroutine, responding to events as they occur.
Now we will see how can we implement this pattern with the help of goroutine
and waitgroups
package main
import (
"fmt"
"sync"
)
// Boring function that returns a channel to send boring messages
func boring(msg string) <-chan string {
ch := make(chan string)
go func() {
defer close(ch) // Close the channel when the goroutine exits
for i := 1; i <= 5; i++ {
ch <- fmt.Sprintf("%s: %d", msg, i)
}
}()
return ch
}
func main() {
aliceCh := boring("Alice")
bobCh := boring("Bob")
// Receive messages concurrently
var wg sync.WaitGroup
wg.Add(2)
go func() {
for msg := range aliceCh {
fmt.Println(msg)
}
wg.Done()
}()
go func() {
for msg := range bobCh {
fmt.Println(msg)
}
wg.Done()
}()
wg.Wait()
}
- Youtube Channel: https://www.youtube.com/@codepiper
- Github Link: CodePiper/GO/concurrency-patterns/Basics at main · arshad404/CodePiper (github.com)