use std::sync::atomic::{AtomicU8, Ordering};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum SupervisorState {
Starting = 0,
Running = 1,
ShuttingDown = 2,
Stopped = 3,
}
impl SupervisorState {
pub fn transition(self, next: SupervisorState) -> Result<SupervisorState, crate::DaemonError> {
let valid = matches!(
(self, next),
(SupervisorState::Starting, SupervisorState::Running)
| (SupervisorState::Starting, SupervisorState::ShuttingDown)
| (SupervisorState::Running, SupervisorState::ShuttingDown)
| (SupervisorState::ShuttingDown, SupervisorState::Stopped)
);
if !valid {
return Err(crate::DaemonError::InvalidStateTransition {
from: format!("{:?}", self),
to: format!("{:?}", next),
});
}
Ok(next)
}
}
pub struct AtomicSupervisorState {
inner: AtomicU8,
}
impl AtomicSupervisorState {
pub fn new(state: SupervisorState) -> Self {
Self {
inner: AtomicU8::new(state as u8),
}
}
pub fn load(&self, ordering: Ordering) -> SupervisorState {
match self.inner.load(ordering) {
0 => SupervisorState::Starting,
1 => SupervisorState::Running,
2 => SupervisorState::ShuttingDown,
_ => SupervisorState::Stopped,
}
}
pub fn store(&self, state: SupervisorState, ordering: Ordering) {
self.inner.store(state as u8, ordering);
}
pub fn transition(
&self,
next: SupervisorState,
ordering: Ordering,
) -> Result<SupervisorState, crate::DaemonError> {
let current = self.load(ordering);
let result = current.transition(next)?;
self.store(result, ordering);
Ok(result)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum WorkerState {
Initializing = 0,
Idle = 1,
Busy = 2,
ShuttingDown = 3,
Stopped = 4,
}
pub struct AtomicWorkerState {
inner: AtomicU8,
}
impl AtomicWorkerState {
pub fn new(state: WorkerState) -> Self {
Self {
inner: AtomicU8::new(state as u8),
}
}
pub fn load(&self, ordering: Ordering) -> WorkerState {
match self.inner.load(ordering) {
0 => WorkerState::Initializing,
1 => WorkerState::Idle,
2 => WorkerState::Busy,
3 => WorkerState::ShuttingDown,
_ => WorkerState::Stopped,
}
}
pub fn store(&self, state: WorkerState, ordering: Ordering) {
self.inner.store(state as u8, ordering);
}
}