Chapter 29 / 51
Volume 4 · Hot Reload Deep Dive

The generation lifecycle: the complete timeline of the reload instant

What happens when a hot reload is submitted while 10 concurrent requests are in flight? This chapter draws the whole process from compile to the old generation's burial — the standard answer to ch. 3's challenge.

Overview

Positioning: assembling the fragments scattered earlier (slots, leases, dual generations, reclamation) into one timeline. Afterwards, every "why" in reload_matrix's assertions has a source.

29.1 Intro

The hardest part of hot reload isn't "swapping the code" but the instant of the swap: is the port still listening? Who owns in-flight requests? How do two generations coexist — and part? The answers hide in two mechanisms: the listener slot (the source of port stability) and the lease (the source of request attribution). String them along a timeline, and you have this chapter.

29.2 The end-to-end timeline

time control thread worker threads listener slot / port ──────────────────────────────────────────────────────────────────── t0 submit intent → freeze snapshot (Revision) t1 compile all candidates (side-effect-free) └ failure → FAILED, stops here (the old generation was never touched) t2 ServiceSwap (old generation exports the snapshot) t3 ═══ crossing the irreversible commit point ═══ t4 new generation ServiceInit (xsSwapTake) 10 in-flight requests port keeps listening "new generation loaded" still served by old gen N (slot unchanged) t5 slot switches its pointer → new connections enter gen N+1 old requests keep running t6 old requests finish one by one → leases returned t7 watch old generation's references …… hit zero t8 GC thread: ServiceUnit → TCC → driver → config (the old generation's burial) note: during t4–t6 both generations coexist; every request sees exactly one generation from start to end
  • t3 is the dividing line: before it everything may fail or cancel; after it only forward is possible (new intents queue up)
  • t5's switch is atomic: a connection begins either from the old generation or the new — there is no "half a new generation"
  • Every request sees exactly one generation throughout — the core invariant of dual generations, and the entire secret of "edit code without dropping connections"

29.3 Listener slots & handoff

the socket of port 8080 is held by a ListenerSlot the slot's pData points at "the current generation" a swap = switching the pointer inside the slot (under a write lock, microseconds) — zero port flicker endpoint comparison: class/ip/port/tls/backlog/recv_limit all identical → in-place handoff endpoints changed → the structural-change path (ch. 13: explicit rejection or a restart prompt)

Handoff is what makes "old and new generations on the same port" possible: the listening socket never closes and reopens — from outside, the service is never unreachable for even a millisecond. TLS endpoints behave the same, and the ClientHello's identity selection (SNI) is bound to the same Accept by the cookie mechanism — handshakes never straddle generations.

29.4 Lease holders

HolderAcquiredReturned
HTTP requestafter Accept, via the slot's current generationresponse complete + body drained (keep-alive holds until the connection ends or the next request re-attributes)
WS / TCP connectionconnection establishedconnection terminal (Close/Abort)
UDP datagramonce per datagramreturned when processing completes
Timerbound to its generation at creationfired, or invalidated by the swap
TAKEOVER connectionat takeoverwhen you finally Close (ch. 25's contract)

So "when does the old generation die" is decided entirely by leases: HTTP returns to zero within seconds after a swap (with keep-alive idle timeouts); long-connection services can drag on — precisely the mechanism behind the lifecycle test asserting "old keep-alive connections keep the old script, terminal reclamation without timeout".

29.5 Contract

  • Attribution: every request sees exactly one generation; the swap switches atomically with zero port flicker.
  • Parallelism: during coexistence the generations don't disturb each other; the old generation accepts no new requests.
  • Reclamation: the old generation's death time = the last lease's return time (GC details in ch. 30).

Common mistakes

Believing the old generation still takes new requests
Symptom
Expectations like "traffic split half old, half new" after a reload come to nothing.
Cause
After the slot switches its pointer, all new connections enter the new generation — the old is out-only. For canary traffic use vhosts / dual servers, not swap ratios.
Taking "no new gen in the logs" as a failed reload
Symptom
After submitting a reload, no new gen number appears; assumed ineffective.
Cause
The gen number lives on the script loaded line; if the content fingerprint is identical (Revision unchanged) or the target is wrong (verify via the result.Target field), no swap ever happened. Trust xsReloadQuery's terminal, not guessed logs.

Exercises

BasicDrawing the timeline from memory

Draw 29.2's timeline with the book closed, marking t3 (the irreversible point) and t5 (the pointer switch).

Acceptance: you can explain why t2 and t8 fall before and after the irreversible point respectively.
AdvancedLease observation

With a long connection (WS) plus three rapid reloads, confirm three pieces of evidence that one connection is served by the same generation throughout (behavior marker, log gen, Swap data).

Acceptance: the three pieces agree; the old generation finalizes only after the connection ends.
ChallengeEnd-to-end imperceptibility

Mirroring reload_matrix: a hammer thread hits /ready every 10ms while you swap 5 times; count failures.

Acceptance: zero failures; the log shows 5 finalized, 0 force-free.

Summary

PointConclusion
Timeline skeletonsnapshot→compile→Swap→irreversible point→Init→pointer switch→leases to zero→GC
Port stabilityslots hold sockets and switch pData — handoff with zero flicker
Dual generationsold is out-only; every request sees one generation
Lease tablerequests/connections/datagrams/timers/takeovers each have acquisition and return points
xrt further reading