Part III — Distributed Transactions & Coordination · Chapter 6

Trace a distributed snapshot across 3 nodes

Hook

Same 3 nodes, same 6 channels, same runSnapshot algorithm from the last chapter — but this time N1 starts the snapshot instead of N0, and there isn't just one message crossing the network when it does, there are two. Can you follow the markers and reconstruct which channels end up holding something, without peeking at the answer first?

Intuition
APP MSGN2 sends $4 to N0 (in flight, before any snapshot begins).
Step 1 of 17
Recorded so far: N0=?, N1=?, N2=?

Step through this trace the same way you did last chapter. N1 initiates now, which changes something structural: since N1 has no incoming marker to trigger its recording, BOTH of its incoming channels — from N0 and from N2 — start "recording" at the very first step, long before N0 or N2 have recorded anything of their own.

Formalize
channel state={m:m received after the recorder’s own state, before the marker on that channel}\text{channel state} = \{\, m : m \text{ received after the recorder's own state, before the marker on that channel} \,\}

The rule is exactly the one from the previous chapter — reused here unchanged, via runSnapshot — applied to a new initiator and a new pair of in-flight messages.

  • N1, the initiator this time — records its own state first, with both incoming channels open from the start.
  • m1 — N2 → N0, $4, sent before the snapshot begins.
  • m2 — N0 → N1, $6, sent after N1 has already started recording that very channel.
  1. Two messages, two channels to watch

    Nothing about the algorithm changes with a second in-flight message — each channel is recorded independently. The only new work is tracking two channels' logs at once instead of one.

  2. The initiator's early start matters

    Because N1 initiates, channel N0 → N1 opens for logging immediately — well before N0 has even recorded its own state. m2 only needs to arrive at N1 before N0's marker does on that same channel, and FIFO ordering guarantees that as long as N0 sent m2 before sending its marker.

Play
APP MSGN2 sends $4 to N0 (in flight, before any snapshot begins).
N0N1: not-yet-recording
N0N2: not-yet-recording
N1N0: not-yet-recording
N1N2: not-yet-recording
N2N0: not-yet-recording
N2N1: not-yet-recording
Step 1 of 17 — total so far: 0 / true total: 30

Scrub through the full trace and watch all 6 channels at once. Two of them — N2 → N0 and N0 → N1 — pick up a logged message before they close; the other four close empty. Watch the running total climb from the recorded-states-only number up to the true total of 30 only once both messages are accounted for.

Worked example

N0 = 10, N1 = 5, N2 = 15 (total 30). N2 → N0 sends $4 before the snapshot; N0 → N1 sends $6 while N1 is already recording that channel.

  1. N1 initiates

    Records its own balance (5). Starts recording both incoming channels, N0→N1 and N2→N1, immediately — it has no triggering marker to exclude one of them.

  2. N0 records on its first marker, after already sending m2

    N0 receives N1's marker and records its own balance. By this point it has already sent the $6 to N1, so N0's recorded balance already reflects that send: 106=410 - 6 = 4.

  3. N2 records on its first marker

    N2 receives N1's marker and records its own balance, which already reflects having sent the $4 to N0 earlier: 154=1115 - 4 = 11.

  4. Both messages land in open channels
    • The $6 arrives at N1 before N0's marker closes channel N0→N1 — logged
    • The $4 arrives at N0 before N2's marker closes channel N2→N0 — logged
    • Every other channel closes with nothing in it
  5. The totals check out

    Recorded states:

    • N0's 44
    • N1's own 55
    • N2's 1111

    Sum: 4+5+11=204 + 5 + 11 = 20. Channel state:

    • N0→N1's 66
    • N2→N0's 44

    Sum: 6+4=106 + 4 = 10. Together: 20+10=3020 + 10 = 30 — exactly the true starting total, split correctly between "already reflected in a node's balance" and "still crossing a channel."

Checkpoint

The snapshot finished across all 6 channels. Click every channel that closed holding an in-flight message. Your running total should reach 30 — the true starting total — only once you've found exactly the right channels.

Reconstructed total: 20 (recorded states alone: 20, true total: 30)
Click channels to select them
Summary
nodesrecorded state+channelsrecorded messages=true total\sum_{\text{nodes}} \text{recorded state} + \sum_{\text{channels}} \text{recorded messages} = \text{true total}

Nothing about the Chandy-Lamport algorithm changed between the last chapter and this one — same marker rule, same runSnapshot function, reused directly rather than reimplemented. What changed is only the trace: a different initiator, and two in-flight messages instead of one, landing on two different channels. That's the real payoff of a marker-based snapshot: it scales to any number of in-flight messages, on any number of channels, without ever needing the system to pause.