A Job Has a Lifetime
Not submitted → assigned → executing → result stored.
The parent returns only after every worker exits.
1 / 8
Not submitted → assigned → executing → result stored.
The parent returns only after every worker exits.
Inputs [6,2,9,4], two workers, square each value.
Index 1 finishes first; index 0 finishes last. What changes?
Only timing. Indexed output remains [36,4,81,16].
workers = min(limit, n).
Each worker runs at most one callback at a time, so active callbacks never exceed the bound. An unbuffered channel prevents an unbounded job backlog.
Producer: send all jobs → close jobs → wait.
Workers: receive → calculate → write one output slot → repeat → exit.
Waiting before closing can leave idle workers and parent waiting on one another.
Each input index appears once; workers write distinct elements. No append, no resizing, no concurrent reader before the join.
The callback still owns synchronization of its other shared state.
Producer blocked sending job 2; workers executing 0 and 1.
Cancel → producer stops and closes → callbacks observe context → workers exit → join → return error.
If a callback ignores context, cancellation cannot force that final join to finish.
BoundMap has no context or error return. All callbacks complete normally; output preserves input order.
A context-aware API needs explicit partial-result and cancellation rules. A ready ctx.Done() case has no priority in select.
Move semaphore acquisition from before go to inside the new goroutine. What remains bounded?
Callback concurrency is bounded; the number of waiting goroutines can grow with the input size.