Module 3 · Exercise 1 · ~30 min · Real Go code

Fan-out / Fan-in Pipeline

Build the textbook concurrent Go pipeline. Source → many workers → merged results. The shape you'll use in any parallel stream processor — including in real Canton transaction-stream indexers.

Where
cd module-03-concurrency/exercises/exercise-01-fan-out
go test -v -race ./...

The -race flag is mandatory.

Three pieces

  1. SourceFromSlice — turn a slice into a closed-when-done channel.
  2. FanOut — N workers reading from input, all writing to one merged output.
  3. Merge — combine many output channels into one.

Mental model

[SourceFromSlice]──┐
                   │
                   ▼
              ┌─────────┐
              │  jobs   │ ← unbounded channel
              └────┬────┘
                   │
        ┌──────────┴──────────┐
        ▼          ▼          ▼
    [worker]   [worker]   [worker]   ← N goroutines, all reading from jobs,
        │          │          │           all writing to results
        ▼          ▼          ▼
              ┌─────────┐
              │ results │
              └────┬────┘
                   │
                   ▼
              caller ranges
              over results

The hard part

Closing channels at the right time. Each worker is a writer to the output. You can't close from inside a worker — there are other writers. You can't close from the source — it doesn't know when consumers finish. The pattern: a separate "watcher" goroutine that waits on a WaitGroup and closes when all workers finish.

If you're stuck, the lesson 2 fan-out code is the template. Don't look at it before trying.