A Job Has a Lifetime

Not submitted → assigned → executing → result stored.

The parent returns only after every worker exits.

1 / 8

Predict the result

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].

2 / 8

Prove the bound

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.

3 / 8

Close then join

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.

4 / 8

Shared slice, separate elements

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.

5 / 8

Cancellation extension

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.

6 / 8

What the lab promises

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.

7 / 8

Exit check

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.

8 / 8
←/→ or click edges to navigate · ? help · N notes · F fullscreen