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}