Skip to content

Instantly share code, notes, and snippets.

@pedrobertao
Created July 17, 2025 15:17
Show Gist options
  • Save pedrobertao/79288f3d330d1c7ce9b3d01432e22ea5 to your computer and use it in GitHub Desktop.
Save pedrobertao/79288f3d330d1c7ce9b3d01432e22ea5 to your computer and use it in GitHub Desktop.
Go concurrency demo using fan-out/fan-in pattern with worker goroutines processing jobs through channels.
package main
import (
"fmt"
"time"
)
// doubleIt is a simple work function that doubles the input value
func doubleIt(a int) int {
return a * 2
}
// workFanOut represents a worker goroutine that processes jobs from a channel
// It takes a jobID for identification, a work function to apply, a jobs channel to read from,
// and a results channel to send completed work to
func workFanOut(jobID int, work func(a int) int, jobs <-chan int, results chan<- int) {
// Process jobs until the jobs channel is closed
for jobToDo := range jobs {
// Apply the work function to the job
workRes := work(jobToDo)
// Simulate work taking time
time.Sleep(2 * time.Second)
fmt.Printf("Worker [%d] done with result [%d] \n", jobID, workRes)
// Send the result back through the results channel
results <- workRes
}
}
func main() {
// Create buffered channels for jobs and results
jobs := make(chan int, 10)
results := make(chan int, 10)
numOfJobs := 3
// Start worker goroutines (fan-out pattern)
// Each worker will process jobs concurrently
for i := 0; i < numOfJobs; i++ {
go workFanOut(i+1, doubleIt, jobs, results)
}
// Send jobs to the workers
for i := 0; i < numOfJobs; i++ {
jobWork := int(i + 10)
fmt.Printf("[%d] Send [%d] \n", i+1, jobWork)
jobs <- jobWork
}
fmt.Println("Waiting job to finish")
// Close the jobs channel to signal workers that no more jobs are coming
close(jobs)
// Fan-in: collect results from all workers
for a := 0; a < numOfJobs; a++ {
res := <-results
fmt.Printf("Result: %d\n", res)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment