Skip to main content

Module warm_swap

Module warm_swap 

Source
Expand description

Warm drain-swap-resume — the click-to-restart path for a wire- and schema-compatible binary swap (see the update PRD, crate::compat, and crate::stager).

This is the “click to restart” layer. A Compatibility::Warm release is a new binary whose fingerprint is otherwise identical to the running one — only binary internals moved — so it cannot be picked up at a turn boundary the way a hot config bundle is (crate::hot_reload); the process itself has to be replaced. But a live conversation must not be yanked mid-turn. This module orchestrates the smallest safe restart: stop admitting new turns, let in-flight turns and paused approvals reach a committed checkpoint, release the single-writer lease, swap the process or image, re-acquire the lease, and resume from the last committed turn.

§It orchestrates; it does not reinvent

Every invariant this path relies on is already built and tested elsewhere — the job here is to sequence those primitives, not to duplicate them:

  • The commit marker is the drain point. A turn is persisted to the event log — bracketed by its turn_start/turn_complete pair — before the harness is dialed, and a turn missing its turn_complete is discarded on replay (the control plane’s filter_committed_turns). So “drain” is not a new barrier: it is waiting for the in-flight turn to reach its existing commit marker, which doubles as the rollback net.
  • The lease is the existing single-writer guard. The per-conversation coordination.k8s.io/v1 Lease already enforces exactly one writer; a warm swap releases it before the swap and re-acquires it after, so the swapped-in process is the sole writer with no split-brain window.
  • Resume is the existing replay path. Restarting from the last committed turn — re-driving any suspended HITL approval — is the same reconstruct the control plane runs on every reconnect.
  • The swap core reuses the stager wholesale. Verifying the new binary’s signature, applying the pointer flip, health-checking it, and auto-rolling back on failure are crate::stager’s job; the only bespoke piece is the Activator, which for a warm swap is a process or image swap.

Because those primitives live in the control plane (a container) while this crate is a foundation component, the orchestrator is expressed over injectable seams — the same shape crate::stager and crate::hot_reload use. The control plane wires each seam to its real drain / lease / resume code; the state machine and its ordering invariant are exercised here without a cluster.

§The classifier gate

Only a release that classifies Compatibility::Warm takes this path. ensure_warm refuses every other verdict: a Compatibility::Hot change reloads at the turn boundary with no restart, a Compatibility::Cold change needs a coordinated fleet redeploy, and an Incompatible bundle was authored against a runtime this build cannot satisfy. The gate runs before any seam is touched, so a non-warm release never closes admission, drains, or releases the lease.

§The ordering invariant

WarmSwap::run walks a fixed sequence, and the ordering is the whole point:

  ensure_warm ─▶ close admission ─▶ drain to committed checkpoint
                                             │
                                             ▼
           release lease ─▶ swap (stager: verify→apply→health→rollback)
                                             │
                                             ▼
           re-acquire lease ─▶ resume from the last committed turn
  • No new turn is admitted once close runs, which is before the drain begins.
  • In-flight turns and paused approvals reach a committed checkpoint before the swap — the checkpoint is captured while the lease is still held.
  • The lease is released before it is re-acquired, so there is never a moment with two writers.
  • Resume restarts from exactly the drained checkpoint, so no committed turn is dropped and none is replayed twice; a paused approval captured in the checkpoint is re-driven.

The lease is re-acquired and the conversation is resumed on whichever binary is live after the swap — the new one on a committed swap, the previous one if the health check rolled back — so a conversation is never left drained-but-dead behind a failed swap.

Structs§

Checkpoint
The drained resume point: the last fully-committed turn plus the paused approvals that must survive the swap.
ResumeReport
What resume did after the swap: where it restarted and how many paused approvals it re-drove.
WarmSwap
The warm drain-swap-resume orchestrator over its four control seams.
WarmSwapReport
The result of a warm swap that got as far as resuming.

Enums§

WarmSwapError
Why a warm swap was refused or could not complete.

Traits§

AdmissionGate
Stops admitting new turns — the readiness flip / turn-admission gate.
Drain
Drains in-flight turns and paused approvals to a committed checkpoint.
LeaseControl
Releases and re-acquires the single-writer per-conversation lease.
Resume
Resumes the conversation from the last committed turn after the swap.

Functions§

ensure_warm
Gate a classification verdict onto the warm path: Ok only for Compatibility::Warm.