Sobes.tech
Senior

Have you ever used Fan-In and Semaphore patterns in your work?

sobes.tech AI

Answer from AI

The Fan-In pattern in Go is often used to merge multiple channels into one, allowing for efficient collection of results from several goroutines. This is useful when aggregating data from different sources.

Example of Fan-In:

func fanIn(channels ...<-chan int) <-chan int {
    out := make(chan int)
    var wg sync.WaitGroup
    wg.Add(len(channels))

    for _, ch := range channels {
        go func(c <-chan int) {
            defer wg.Done()
            for v := range c {
                out <- v
            }
        }(ch)
    }

    go func() {
        wg.Wait()
        close(out)
    }()

    return out
}

The Semaphore pattern is used to limit the number of goroutines executing simultaneously to control load and resources. In Go, this is implemented via a buffered channel acting as a semaphore.

Example of Semaphore:

sem := make(chan struct{}, maxConcurrent)

for _, task := range tasks {
    sem <- struct{}{} // acquire semaphore
    go func(t Task) {
        defer func() { <-sem }() // release semaphore
        process(t)
    }(task)
}

I used both patterns for managing concurrency and synchronization in high-load services in Go.