v0.3.9-pre.002
This commit is contained in:
138
crates/ksp-worker-api/src/snapshot.rs
Normal file
138
crates/ksp-worker-api/src/snapshot.rs
Normal file
@@ -0,0 +1,138 @@
|
||||
// file: crates/ksp-worker-api/src/snapshot.rs
|
||||
// version: 1
|
||||
|
||||
/// Monotone sequence attached to one latest-value Worker snapshot stream.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub struct WorkerSnapshotSequence(u64);
|
||||
|
||||
impl 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<Self> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 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 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::boxed::Box<dyn std::future::Future<Output = crate::WorkerSnapshot> + 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 WorkerSnapshotSequence(u64::MAX);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "../unit_tests/snapshot.rs"]
|
||||
mod tests;
|
||||
Reference in New Issue
Block a user