Module outbound_queue

Module outbound_queue 

Source
Expand description

Disk-backed durable outbound event queue (Plan 07 locked-in decision; RFC-0005 §9.7).

Each event is one file on disk under {state_dir}/outbound-queue/, named {seq:020}-{hostname}-{rollout}-{event_kind}.json. Zero- padded seq so directory listing is in seq-order. Atomic write via tmp + rename so a crash mid-write leaves no partially-formed file visible to the drainer. On successful POST, the file is deleted.

Properties:

  • Survives agent process crashes: every outbound event hits disk before the network call returns.
  • Single fsync per event: the rename hops the rename-survives- reboot guarantee on POSIX filesystems; the data fsync ensures the bytes are durable before the rename swings the pointer.
  • Replay-from-seq friendly: a CP X-Nixfleet-Replay-From: N response triggers a directory scan for files with seq ≥ N.
  • Crash mid-write: a partial .tmp file is invisible to OutboundQueue::scan_pending because the filename pattern filters out non-.json paths. The next restart’s drainer picks up where it left off.

Structs§

OutboundQueue
Disk-backed queue handle. Cheap to clone via Arc.
QueuedEvent
One entry in the on-disk queue. Persisted as JSON via serde. payload is the typed wire event (RFC-0004 §2 lift: the wire envelope + AgentEvent live in nixfleet-proto, both sides of the agent <-> CP boundary import the same types). The outbound worker wraps each QueuedEvent in an AgentEventEnvelope at POST time.

Functions§

filename_for 🔒
{seq:020}-{hostname}-{rollout}-{event_kind}.json. The zero-padded seq gives lexicographic = chronological filename order; the .json suffix is what scan_pending filters on (vs .tmp).
outbound_event_kind
Map an OutboundAgentEvent to its kebab-case event_kind discriminator (used in the filename + the OutboundEventKind enum in db/event_log on the CP side).
outbound_event_seq
Read the seq field off an OutboundAgentEvent.
sanitize 🔒
Filename sanitisation: replace path separators + spaces with _. Belt-and-braces; the wire types should already constrain these strings to URL-safe shapes, but we don’t trust the input.
write_atomic 🔒