Chapter 19 — worked answers
1. Strict comparison and sampling
The implementation uses LastHeartbeatAt.Before(cutoff), not less-than-or-equal. Equality is therefore skipped. The next ticker can detect staleness, adding up to a cadence phase under normal scheduling; do not claim exact detection latency without observed timestamps and scheduling assumptions.
2. Decision completion differs from removal
nodeDrainStatusLocked increments RemainingTasks only for tasks still desired neither stopped nor removed. It can return complete after stop intent is set while an agent has not removed the container. Verify actual task removal and Docker identity before equating drain status with an empty host.
3. Conservative stateful policy is not fencing
Both get a node_lost condition. Stateless tasks become desired removed, actual failed and eligible for replacement; Stateful tasks retain their state in this branch. Neither proves exclusive runtime data access. A partitioned old process can keep running, and preserving a stateful task does not recover its data.
4. Evidence must span both owners
Use two disposable agents and an owned server or local proxy. Retain nodeA/taskA/containerA and nodeB/taskB/containerB plus UTC samples of heartbeat, central assignment and both direct endpoints. Pause only the owned agent, preserve old-container responses after replacement starts, then resume and inspect cleanup. That demonstrates the bounded scenario without assuming all partitions behave identically.
Return to Chapter 19.