// file: crates/ksp-worker-api/src/snapshot.rs // version: 3 /// Monotone sequence attached to one latest-value Worker snapshot stream. #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct WorkerSnapshotSequence(u64); impl crate::WorkerSnapshotSequence { /// Creates the initial sequence position for one Worker snapshot stream. #[must_use] pub const fn initial() -> Self { return Self(0); } /// Returns the opaque numeric position carried by this sequence. #[must_use] pub const fn value(&self) -> u64 { return self.0; } /// Advances the sequence exactly once or reports exhaustion without wrapping. pub fn next(&self) -> crate::Result { let next = match self.0.checked_add(1) { std::option::Option::Some(value) => value, std::option::Option::None => { return std::result::Result::Err( crate::Error::new(crate::ERROR_CODE_WORKER_SNAPSHOT_SEQUENCE_EXHAUSTED, "Worker snapshot sequence exhausted") .with_context("sequence", self.0.to_string()), ); }, }; return std::result::Result::Ok(Self(next)); } /// Reports whether this sequence is strictly newer than an observed sequence. #[must_use] pub const fn is_after(&self, observed: Self) -> bool { return self.0 > observed.0; } #[cfg(test)] const fn exhausted_for_test() -> Self { return Self(u64::MAX); } } /// Fixed common latest-value snapshot exposed by every Worker implementation. #[derive(Clone, Eq, PartialEq)] pub struct WorkerSnapshot { id: crate::WorkerId, kind: crate::WorkerKindCode, sequence: crate::WorkerSnapshotSequence, state: crate::WorkerState, health: crate::WorkerHealth, activity: crate::WorkerActivity, } impl crate::WorkerSnapshot { /// Creates one immutable common Worker snapshot from already validated values. #[must_use] pub const fn new( id: crate::WorkerId, kind: crate::WorkerKindCode, sequence: crate::WorkerSnapshotSequence, state: crate::WorkerState, health: crate::WorkerHealth, activity: crate::WorkerActivity, ) -> Self { return Self { id, kind, sequence, state, health, activity }; } /// Returns the logical Worker identity. #[must_use] pub const fn id(&self) -> &crate::WorkerId { return &self.id; } /// Returns the stable Worker family code. #[must_use] pub const fn kind(&self) -> &crate::WorkerKindCode { return &self.kind; } /// Returns the monotone sequence of this latest value. #[must_use] pub const fn sequence(&self) -> crate::WorkerSnapshotSequence { return self.sequence; } /// Returns the lifecycle state represented by this snapshot. #[must_use] pub const fn state(&self) -> crate::WorkerState { return self.state; } /// Returns the operational health represented by this snapshot. #[must_use] pub const fn health(&self) -> crate::WorkerHealth { return self.health; } /// Returns the generic activity represented by this snapshot. #[must_use] pub const fn activity(&self) -> crate::WorkerActivity { return self.activity; } } impl std::fmt::Debug for crate::WorkerSnapshot { fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { return formatter .debug_struct("WorkerSnapshot") .field("id", &self.id) .field("kind", &self.kind) .field("sequence", &self.sequence) .field("state", &self.state) .field("health", &self.health) .field("activity", &self.activity) .finish(); } } /// Runtime-neutral future returned while observing a latest-value Worker snapshot source. pub type WorkerSnapshotFuture<'a> = std::pin::Pin + std::marker::Send + 'a>>; /// Runtime-neutral read and change-wait contract for one latest-value Worker snapshot stream. pub trait WorkerSnapshotSource: std::marker::Send + std::marker::Sync { /// Returns the complete current common Worker snapshot without replaying prior updates. #[must_use] fn current(&self) -> crate::WorkerSnapshot; /// Waits for a snapshot newer than `observed`, returning the complete current value after coalescing intermediate updates. fn wait_for_change(&self, observed: crate::WorkerSnapshotSequence) -> crate::WorkerSnapshotFuture<'_>; } #[cfg(test)] fn exhausted_snapshot_sequence() -> crate::WorkerSnapshotSequence { return crate::WorkerSnapshotSequence::exhausted_for_test(); } #[cfg(test)] #[path = "../unit_tests/snapshot.rs"] mod tests;