How would you arrange switches so a chain decodes a large file off the window worker but paints progress on it?
answer
- think segments, not stages
- each boundary opens a new segment
- the last segment receives the values
- boundaries never reach backwards
- one handoff per value per boundary
basics
~20 sRelocate the producing work once, so the read and decode run in the background, then place one forward-only boundary just before the painting stage so values arrive on the window worker. Each boundary opens a new segment.
solid answer
~40 sThink of the chain as **segments**, not stages. The switch that relocates producing work owns the first segment: the source and everything after it until the first forward-only boundary. Each forward-only boundary you add starts a fresh segment running on its worker, covering the stages between it and the next boundary. So here: one producing-side switch puts reading and decoding in the background, and one boundary written immediately before the painting stage puts only the painting on the window worker. If checksumming or compression deserves a different worker from the reading, add one more boundary before it — that is three segments in one chain, which is legitimate. Keep the count low: every boundary costs a handoff per value, and progress updates are frequent.
code
pseudocode · 12 lineschain =
source: read_large_file(path)
run_producing_on(io_worker) // segment 1: the source and what follows
then: decode(chunk)
deliver_following_on(cpu_worker) // segment 2 starts here
then: checksum(chunk)
then: to_progress_percent(chunk)
deliver_following_on(window_worker) // segment 3 starts here
then: paint(percent)
// segment 1 = reading + decoding, segment 2 = checksum + percentage,
// segment 3 = painting onlygo deeper
Hold on to the picture: a chain is cut into segments at each switch that relocates what follows, and everything inside a segment runs on that segment's worker.
Explain which stages land in which segment for a written chain, and say why a boundary placed at the top moves the wrong stages instead of the ones you wanted.
Show operating judgment: pick the smallest number of segments that meets the requirements, justify each handoff against the value rate, and cut the rate before adding a worker.
Set the convention. Decide how many segments a chain may have before it needs a rationale, and require every published chain to state the worker its values are delivered on.
## A chain is a sequence of segments Once more than one switch is in play, the useful mental model is not *stage to worker* but **segment to worker**. Draw the chain top to bottom and cut it at every forward-only boundary. Each cut starts a new segment, and every stage inside a segment runs on that segment's worker. - **The first segment** starts at the source. Its worker is set by the producing-side switch nearest the source, or, if there is none, by the worker that attached the subscriber. - **Every later segment** starts at a forward-only boundary and runs on that boundary's worker until the next boundary. - **The last segment** is the one the subscriber's own callback runs in. That is the segment to check against any requirement about where values must be received. ## Applying it to the file-loading window A plausible chain: read the file in chunks, decode each chunk, compute a running percentage, paint the progress bar. The read must not run on the window worker; the painting must. Two switches are enough: 1. Relocate the producing work onto a worker suited to a long read. This covers the source and every stage down to the first boundary, so reading and decoding both move. 2. Place one forward-only boundary immediately before the painting stage. Only the painting ends up on the window worker. If profiling shows decoding competing with the read, insert a second boundary between them and give decoding its own worker. Now the chain has three segments. | Segment | Runs on | Stages inside it | |---|---|---| | From the source to the first boundary | the producing-side switch's worker | reading chunks | | From the first boundary to the second | a worker suited to computation | decoding, percentage arithmetic | | From the last boundary to the subscriber | the window worker | painting the progress bar | ## Rules that fall out of the model 1. **A boundary never reaches backwards.** Writing the window-worker boundary at the top of the chain does not bring the painting back; it brings everything after it, including the read's downstream stages, onto the window worker — the opposite of what was wanted. 2. **The last boundary wins for delivery.** Whatever you do in the middle, the segment containing the subscriber's callback is the one that decides where values are received. 3. **Ordering survives the cuts.** Values still cross each boundary one at a time and in order, so segmenting does not reorder a progress sequence. What it adds is latency, not disorder. 4. **A boundary written after the last stage buys nothing but a hop.** It creates a segment containing only the subscriber's callback; if that callback has no worker requirement, the hop is pure cost. ## The cost side of stacking Every boundary is a handoff per value: queue the value, wake the receiving worker, resume. That is negligible once per file and significant once per chunk if the chunks are small and frequent. Two practical consequences: - **Count boundaries against value rate, not against stage count.** Three segments over a hundred thousand tiny values is a very different bill from three segments over a hundred. - **Reduce the rate before adding a segment.** A progress bar cannot show more than a few dozen meaningful updates; if the percentage stage emits far more often than the window can paint, the fix is upstream of the boundary rather than a faster worker behind it. ## The reviewable outcome A well-arranged chain can be described in one sentence per segment — *read in the background, decode there too, paint on the window worker* — and a reviewer can check each switch against that sentence. A chain with switches sprinkled between every pair of stages usually cannot be described that way at all, which is itself the finding: it means nobody decided which segments the chain should have, they just kept adding relocations until the symptom went away.
- What happens if the window-worker boundary is written first instead of last?Everything after it runs on the window worker, which now includes the decoding and percentage stages. A boundary has forward reach only, so writing it early does not pull the painting back — it pushes the wrong work forward onto the worker you were protecting.
- Does segmenting a chain risk delivering progress values out of order?No. Values cross each boundary one at a time and in order, so the sequence stays intact. What a boundary adds is latency per value and scheduling cost, not reordering.
- When is a third segment worth its handoff?When the stages on either side genuinely contend — a long read and a computation heavy enough to delay it — and when the value rate is low enough that a hop per value is small beside the work. Otherwise fold them into one segment.
saying these in an interview costs you the question
- Thinks a boundary written early can pull later stages back
- Expects only the immediately following stage to move, not the whole segment
- Adds a boundary between every pair of stages by reflex
- Claims segmenting a chain reorders the values
- Puts a boundary after the final stage and calls it a fix
- Ignores that each boundary costs a handoff per value