1use std::sync::atomic::{AtomicU8, Ordering};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[repr(u8)]
8pub enum SupervisorState {
9 Starting = 0,
11 Running = 1,
13 ShuttingDown = 2,
15 Stopped = 3,
17}
18
19impl SupervisorState {
20 pub fn transition(self, next: SupervisorState) -> Result<SupervisorState, crate::DaemonError> {
22 let valid = matches!(
23 (self, next),
24 (SupervisorState::Starting, SupervisorState::Running)
25 | (SupervisorState::Starting, SupervisorState::ShuttingDown)
26 | (SupervisorState::Running, SupervisorState::ShuttingDown)
27 | (SupervisorState::ShuttingDown, SupervisorState::Stopped)
28 );
29 if !valid {
30 return Err(crate::DaemonError::InvalidStateTransition {
31 from: format!("{:?}", self),
32 to: format!("{:?}", next),
33 });
34 }
35 Ok(next)
36 }
37}
38
39pub struct AtomicSupervisorState {
41 inner: AtomicU8,
42}
43
44impl AtomicSupervisorState {
45 pub fn new(state: SupervisorState) -> Self {
46 Self {
47 inner: AtomicU8::new(state as u8),
48 }
49 }
50
51 pub fn load(&self, ordering: Ordering) -> SupervisorState {
52 match self.inner.load(ordering) {
53 0 => SupervisorState::Starting,
54 1 => SupervisorState::Running,
55 2 => SupervisorState::ShuttingDown,
56 _ => SupervisorState::Stopped,
57 }
58 }
59
60 pub fn store(&self, state: SupervisorState, ordering: Ordering) {
61 self.inner.store(state as u8, ordering);
62 }
63
64 pub fn transition(
66 &self,
67 next: SupervisorState,
68 ordering: Ordering,
69 ) -> Result<SupervisorState, crate::DaemonError> {
70 let current = self.load(ordering);
71 let result = current.transition(next)?;
72 self.store(result, ordering);
73 Ok(result)
74 }
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
79#[repr(u8)]
80pub enum WorkerState {
81 Initializing = 0,
83 Idle = 1,
85 Busy = 2,
87 ShuttingDown = 3,
89 Stopped = 4,
91}
92
93pub struct AtomicWorkerState {
95 inner: AtomicU8,
96}
97
98impl AtomicWorkerState {
99 pub fn new(state: WorkerState) -> Self {
100 Self {
101 inner: AtomicU8::new(state as u8),
102 }
103 }
104
105 pub fn load(&self, ordering: Ordering) -> WorkerState {
106 match self.inner.load(ordering) {
107 0 => WorkerState::Initializing,
108 1 => WorkerState::Idle,
109 2 => WorkerState::Busy,
110 3 => WorkerState::ShuttingDown,
111 _ => WorkerState::Stopped,
112 }
113 }
114
115 pub fn store(&self, state: WorkerState, ordering: Ordering) {
116 self.inner.store(state as u8, ordering);
117 }
118}