use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{Duration, Instant};
use super::event::{ChainId, DaemonRef, NodeId};
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct ActionId(
pub u64,
);
#[derive(Debug, Default)]
pub struct AllocateActionId {
counter: AtomicU64,
}
impl AllocateActionId {
pub fn new() -> Self {
Self {
counter: AtomicU64::new(1),
}
}
pub fn next(&self) -> ActionId {
ActionId(self.counter.fetch_add(1, Ordering::Relaxed))
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum MeshOsAction {
StartDaemon {
daemon: DaemonRef,
},
StopDaemon {
daemon: DaemonRef,
reason: String,
deadline: Instant,
},
PullReplica {
chain: ChainId,
source: NodeId,
},
DropReplica {
chain: ChainId,
},
RequestPlacement {
chain: ChainId,
exclude: Vec<NodeId>,
target: Option<NodeId>,
},
RequestEviction {
chain: ChainId,
victim: NodeId,
},
MigrateBlob {
blob: u64,
from: NodeId,
to: NodeId,
},
ReduceHeat {
blob: u64,
by: u32,
},
MarkAvoid {
peer: NodeId,
reason: String,
ttl: Duration,
},
ApplyBackoff {
daemon: DaemonRef,
until: Instant,
},
CommitMaintenanceTransition {
node: NodeId,
target: MaintenanceTransition,
},
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum MaintenanceTransition {
EnteringMaintenance,
Maintenance,
ExitingMaintenance,
DrainFailed {
reason: String,
},
Recovery,
Active,
}
#[derive(Clone, Debug, PartialEq)]
pub struct PendingAction {
pub id: ActionId,
pub action: MeshOsAction,
pub emitted_at: Instant,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn allocator_hands_out_monotonic_unique_ids() {
let alloc = AllocateActionId::new();
let a = alloc.next();
let b = alloc.next();
let c = alloc.next();
assert_eq!(a, ActionId(1));
assert_eq!(b, ActionId(2));
assert_eq!(c, ActionId(3));
assert!(a != b && b != c);
}
}