nixfleet_state_machine/rollout/
effect.rs

1//! Rollout-level effects (RFC-0008 §5). Descriptive data; the CP applier
2//! interprets each variant against the `rollouts` / `quarantined_closures`
3//! derived-view tables (RFC-0008 §6.3 + §6.4).
4//!
5//! Effects-as-data discipline (RFC-0006 §3): the reducer cannot perform
6//! I/O; the applier has one match arm per variant. Adding a variant
7//! is a compiler-enforced change at every applier.
8
9use chrono::{DateTime, Utc};
10use serde::{Deserialize, Serialize};
11
12use crate::rollout::state::{ChannelId, ClosureHash, RolloutId, RolloutState};
13
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15pub enum RolloutEffect {
16    /// Persist a rollout-level state transition. Drives the
17    /// `rollouts.state` column update; the applier co-writes the
18    /// corresponding `event_log` row (`kind = 'rollout_event'`).
19    RecordRolloutTransition {
20        rollout_id: RolloutId,
21        from: RolloutState,
22        to: RolloutState,
23        at: DateTime<Utc>,
24    },
25    /// Monotonic wave-index advance on the `rollouts.current_wave` column.
26    UpdateCurrentWave { rollout_id: RolloutId, wave: u32 },
27    /// A rollback completed; insert a row into `quarantined_closures`
28    /// referencing the triggering `event_log` seq (NULL-able under v0.2.1
29    /// baseline; RFC-0008 §6.1 item 3).
30    InsertQuarantineFromRollout {
31        channel: ChannelId,
32        closure_hash: ClosureHash,
33    },
34    /// A rollout entered a terminal-set state (Terminal | Superseded |
35    /// Failed | Reverted); schedule its retention-expiry event for the
36    /// configured delay. The applier queues a delayed `RetentionExpired`
37    /// re-entry into the reducer.
38    SchedulePruning {
39        rollout_id: RolloutId,
40        delay_seconds: i64,
41    },
42}
43
44impl RolloutEffect {
45    pub fn kind(&self) -> &'static str {
46        match self {
47            RolloutEffect::RecordRolloutTransition { .. } => "RecordRolloutTransition",
48            RolloutEffect::UpdateCurrentWave { .. } => "UpdateCurrentWave",
49            RolloutEffect::InsertQuarantineFromRollout { .. } => "InsertQuarantineFromRollout",
50            RolloutEffect::SchedulePruning { .. } => "SchedulePruning",
51        }
52    }
53}