Skip to main content

rust_supervisor/control/
command.rs

1//! Runtime control command contract.
2//!
3//! This module owns auditable command inputs and command results. Runtime code
4//! executes these commands and records state changes.
5
6use crate::id::types::{ChildId, SupervisorPath};
7use crate::shutdown::coordinator::ShutdownResult;
8use serde::{Deserialize, Serialize};
9use uuid::Uuid;
10
11/// Stable identifier for an accepted control command.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13pub struct CommandId {
14    /// UUID value assigned when a command is created.
15    pub value: Uuid,
16}
17
18impl CommandId {
19    /// Creates a command identifier.
20    ///
21    /// # Arguments
22    ///
23    /// This function has no arguments.
24    ///
25    /// # Returns
26    ///
27    /// Returns a new [`CommandId`].
28    ///
29    /// # Examples
30    ///
31    /// ```
32    /// let id = rust_supervisor::control::command::CommandId::new();
33    /// assert!(!id.value.is_nil());
34    /// ```
35    pub fn new() -> Self {
36        Self {
37            value: Uuid::new_v4(),
38        }
39    }
40}
41
42impl Default for CommandId {
43    /// Creates the default command identifier.
44    fn default() -> Self {
45        Self::new()
46    }
47}
48
49/// Audit metadata attached to each runtime control command.
50#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
51pub struct CommandMeta {
52    /// Command identifier used for audit correlation.
53    pub command_id: CommandId,
54    /// Actor that requested the command.
55    pub requested_by: String,
56    /// Human-readable command reason.
57    pub reason: String,
58}
59
60impl CommandMeta {
61    /// Creates command metadata.
62    ///
63    /// # Arguments
64    ///
65    /// - `requested_by`: Actor that requested the command.
66    /// - `reason`: Human-readable command reason.
67    ///
68    /// # Returns
69    ///
70    /// Returns a [`CommandMeta`] value with a generated command identifier.
71    pub fn new(requested_by: impl Into<String>, reason: impl Into<String>) -> Self {
72        Self {
73            command_id: CommandId::new(),
74            requested_by: requested_by.into(),
75            reason: reason.into(),
76        }
77    }
78}
79
80/// Runtime command sent to the control loop.
81#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
82pub enum ControlCommand {
83    /// Adds a child description under a supervisor path.
84    AddChild {
85        /// Audit metadata for the command.
86        meta: CommandMeta,
87        /// Target supervisor path.
88        target: SupervisorPath,
89        /// Child manifest text owned by the caller.
90        child_manifest: String,
91    },
92    /// Removes a child after shutting it down.
93    RemoveChild {
94        /// Audit metadata for the command.
95        meta: CommandMeta,
96        /// Target child identifier.
97        child_id: ChildId,
98    },
99    /// Restarts a child explicitly.
100    RestartChild {
101        /// Audit metadata for the command.
102        meta: CommandMeta,
103        /// Target child identifier.
104        child_id: ChildId,
105    },
106    /// Pauses automatic governance for a child.
107    PauseChild {
108        /// Audit metadata for the command.
109        meta: CommandMeta,
110        /// Target child identifier.
111        child_id: ChildId,
112    },
113    /// Resumes automatic governance for a child.
114    ResumeChild {
115        /// Audit metadata for the command.
116        meta: CommandMeta,
117        /// Target child identifier.
118        child_id: ChildId,
119    },
120    /// Quarantines a child and stops automatic restarts.
121    QuarantineChild {
122        /// Audit metadata for the command.
123        meta: CommandMeta,
124        /// Target child identifier.
125        child_id: ChildId,
126    },
127    /// Starts shutdown for the whole supervisor tree.
128    ShutdownTree {
129        /// Audit metadata for the command.
130        meta: CommandMeta,
131    },
132    /// Reads current runtime state.
133    CurrentState {
134        /// Audit metadata for the command.
135        meta: CommandMeta,
136    },
137}
138
139impl ControlCommand {
140    /// Returns audit metadata for this command.
141    ///
142    /// # Arguments
143    ///
144    /// This function has no arguments.
145    ///
146    /// # Returns
147    ///
148    /// Returns a shared reference to [`CommandMeta`].
149    pub fn meta(&self) -> &CommandMeta {
150        match self {
151            Self::AddChild { meta, .. }
152            | Self::RemoveChild { meta, .. }
153            | Self::RestartChild { meta, .. }
154            | Self::PauseChild { meta, .. }
155            | Self::ResumeChild { meta, .. }
156            | Self::QuarantineChild { meta, .. }
157            | Self::ShutdownTree { meta }
158            | Self::CurrentState { meta } => meta,
159        }
160    }
161}
162
163/// State assigned to a managed child by the control loop.
164#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
165pub enum ManagedChildState {
166    /// Child is known and running.
167    Running,
168    /// Child is paused by operator command.
169    Paused,
170    /// Child is quarantined and cannot auto-restart.
171    Quarantined,
172    /// Child was removed from active governance.
173    Removed,
174}
175
176/// Current runtime state returned by `current_state`.
177#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
178pub struct CurrentState {
179    /// Number of children known to the control loop.
180    pub child_count: usize,
181    /// Whether tree shutdown has completed.
182    pub shutdown_completed: bool,
183}
184
185/// Result returned after a control command is executed.
186#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
187pub enum CommandResult {
188    /// Child was accepted by the control loop.
189    ChildAdded {
190        /// Child manifest stored by the runtime.
191        child_manifest: String,
192    },
193    /// Child state after a command.
194    ChildState {
195        /// Target child identifier.
196        child_id: ChildId,
197        /// Current managed child state.
198        state: ManagedChildState,
199        /// Whether the command reused an existing state.
200        idempotent: bool,
201    },
202    /// Current state query result.
203    CurrentState {
204        /// Runtime current state.
205        state: CurrentState,
206    },
207    /// Shutdown command result.
208    Shutdown {
209        /// Shutdown phase and cause.
210        result: ShutdownResult,
211    },
212}