The Fan-In Pattern is a parallel programming design pattern where multiple goroutines send their results to a common channel. This allows you to gather or process results from multiple sources concurrently.
- Fan-In refers to "gathering" or "merging" results from multiple sources.
- This pattern is often used to merge results or data from multiple worker goroutines.
- Multiple sources: Several worker goroutines perform tasks and send their results into separate channels.
- Result collection: A central channel collects results from the workers’ channels.
- Results: The main program or another goroutine can receive the merged results from the common channel.
The diagram helps visualize the Fan-In pattern:
Worker 1 Worker 2 Worker 3
| | |
v v v
---------------
|
v
Output
- Workers: The worker goroutines send their results into separate channels.
- Output: The results from multiple workers are gathered into a single channel.
Here’s an example of how to implement the Fan-In pattern in Go. In this example, worker goroutines perform simple tasks and send their results into a common channel.
package main
import (
"fmt"
"sync"
)
func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
defer wg.Done() // Ensure worker completes the task
for job := range jobs {
fmt.Printf("Worker %d is processing job %d\n", id, job)
results <- job * 2 // Assume the task is doubling the value
}
}
func main() {
jobs := make(chan int, 10) // Channel for jobs
results := make(chan int, 10) // Channel to collect results from workers
var wg sync.WaitGroup
// Create 3 workers
for i := 1; i <= 3; i++ {
wg.Add(1)
go worker(i, jobs, results, &wg)
}
// Send jobs to the jobs channel
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs) // Close the jobs channel after sending tasks
// Wait for all workers to complete
wg.Wait()
close(results) // Close the results channel after completion
// Collect results from the results channel
for result := range results {
fmt.Println("Result:", result)
}
}
jobs
channel: This channel holds the jobs (integer values) that need to be processed. Each job represents a task that a worker will process.worker
function:- Each worker receives jobs from the jobs channel and processes them. In this example, the worker simply prints a message indicating that it's processing a job.
- The workers are goroutines that operate concurrently, meaning they process tasks at the same time.
sync.WaitGroup
: Ensures that the main function waits for all workers to finish their tasks before exiting.- Goroutines: Each worker is a separate goroutine, allowing concurrent processing of tasks.
- Result Gathering: You can collect results from multiple sources (workers) into a single channel.
- Resource Optimization: Worker goroutines run concurrently and send their results to the common channel without direct synchronization with each other.
- Scalability: You can easily add more workers without significantly changing the main program.
- Synchronization:
- Use
sync.WaitGroup
or other synchronization techniques to ensure that the main program waits for all workers to complete their tasks before exiting.
- Use
- Channel Management:
- Ensure the results channel is closed properly after all workers are done to avoid deadlocks or missing results.
- Worker Coordination:
- The Fan-In pattern requires worker goroutines to synchronize their results and send them into the common channel, so be sure to handle this coordination properly to avoid data loss.
- The Fan-In Pattern is an efficient way to collect results from multiple goroutines and process them concurrently in Go.
- This design pattern can be combined with the Fan-Out Pattern to optimize performance when processing tasks in parallel.