Expand description
CP runtime: MPSC reducer loop + applier + workers (RFC-0006 §7.2).
§Architecture
manifest_poll ─┐
event_ingest ─┼──▶ mpsc::Sender<ReducerInput> ───▶ reducer task ───▶ applier
heartbeat_rx ─┤ │
dispatch lp ─┘ ▼
(step + plan_next)Invariants (do not violate without an RFC amendment):
-
One MPSC, one mutator. The reducer task is the only thing that calls
nixfleet_state_machine::stepornixfleet_reconciler::planner::plan_next. Workers emitReducerInputvalues; the applier executes the resulting effects. A second writer “for performance” is the defect class that the v0.2 fold is folding away — don’t reintroduce it. -
CP mirror runs the same
step()as the agent. Identical transitions forLocal*andRemote*event pairs by construction (RFC-0006 §2 principle 4). No “leaner” CP-side reimplementation. -
Shutdown via oneshot drop. The reducer task owns a vector of [
tokio::sync::oneshot::Sender<()>]; each worker holds the matchingShutdownToken(wrapping aReceiver). Reducer exit drops every sender, every worker’sselect!shutdown arm fires, workers exit cleanly. No leaks if a worker hangs on its own — theJoinHandledrain inserver::modaborts past the deadline. -
Bounded channels. The input MPSC and any internal applier queues have explicit
boundedcapacities with a sizing rationale in a comment — neverunbounded, never “let’s start at 4096 and see.”
Re-exports§
pub use event_log_writer::EVENT_LOG_CHANNEL_CAPACITY;pub use event_log_writer::EventLogTx;
Modules§
- applier
- Imperative shell for the pure planner + reducer (RFC-0006 §7.2).
- event_
log_ writer - Event-log writer task: dedicated consumer of
EventLogEntryvalues the reducer-task applier emits, persisting them to SQLite outside the reducer’s critical section. - reducer 🔒
- Reducer task body: the single mutator of CP-mirror state.
- workers
- Workers — the I/O-bearing edges around the pure reducer.
Structs§
- Heartbeat
Reply - Heartbeat reply: drift detected ⇒
replay_fromisSome(last_known_seq); agent should re-POST events from that seq onward (RFC-0005 §4.3).bootstrap_rollouts(LIFT #3) carries CP’s view of active rollouts the agent should rehydrate when its reducer was lost (boot-recovery shape; heartbeat carriedrollout_id = Nonebut CP holds non-terminal records for the host). - Runtime
Handle - Handle returned by
spawn. Holds the input channel sender (cloneable for HTTP route handlers) and the reducer-taskJoinHandle. The handle must outlive every cloned sender, otherwise the reducer task exits prematurely. - Shutdown
Token - Shutdown signal handed to a worker at spawn time. Workers select! between
their input source and
&mut self.0; reducer-task exit drops the matchedSender<()>and the receiver resolves withErr(RecvError). Workers treat any resolution as “shutdown” and exit cleanly.
Enums§
- Reducer
Input - Reducer-task inputs. Workers and HTTP route handlers obtain a
mpsc::Sender<ReducerInput>from theRuntimeHandleand emit values of this type. Variants partition by the reducer action they drive:
Constants§
- REDUCER_
INPUT_ 🔒CAPACITY - Input channel depth. Sized for ~512 in-flight events plus headroom for
burst: a 256-host fleet, ~2 events/host during peak rollout activation,
rounded to power-of-two and doubled. Backpressure surfaces at HTTP
handlers via
try_send→ 503 (caller retries), preserving the pull-only agent contract (RFC-0005 §2.1 — CP never pushes, agents always retry).
Functions§
- spawn
- Spawn the reducer + worker constellation. Returns a
RuntimeHandlethe caller wires into the server shutdown drain. - spawn_
drain_ 🔒only_ writer - Fallback writer when CP runs in in-memory mode (no
db_pathflag). Just drains entries silently so the channel never fills up. Production paths always configure a DB.