Загрузчик логов, обработчик очереди сообщений, ETL-конвейер, агрегатор метрик
устроены одинаково: данные проходят через несколько стадий, некоторые стадии
распараллелены, в конце результаты собираются вместе. Блок учит собирать такие
конструкции из каналов и горутин: где распараллелить, где слить потоки обратно, как
ограничить число одновременных воркеров и как сгруппировать мелкие операции в пачки.
Сквозная тема — кто закрывает каналы. Закрывает тот, кто точно знает, что отправок
больше не будет: единственный отправитель или координатор, дождавшийся всех
отправителей. Тогда закрытие проходит вниз по конвейеру и по очереди завершает все
стадии.
Каналы — владение закрытием и направления каналов как контракт
между стадиями.
// Идиома блока: fan-in закрывает выход ровно после всех источников.var wg sync.WaitGroupfor _, c := range channels { wg.Add(1) go func(c <-chan int) { defer wg.Done() for v := range c { out <- v } }(c)}go func() { wg.Wait(); close(out) }()