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}