Skip to main content

noether_store/
async_traits.rs

1//! Async stage-store abstraction.
2//!
3//! Suitable for database-backed stores (PostgreSQL, etc.) that can serve many
4//! concurrent Axum handlers without blocking the executor.
5//!
6//! All methods take `&self` — implementations are expected to hold their own
7//! internal synchronisation (a connection pool, a `tokio::sync::Mutex`, …).
8//! All return types are owned so they are safe to `.await` across task
9//! boundaries without lifetime issues.
10
11use crate::traits::{StoreError, StoreStats};
12use noether_core::stage::{Stage, StageId, StageLifecycle};
13
14/// Async storage abstraction for stages.
15#[async_trait::async_trait]
16pub trait AsyncStageStore: Send + Sync {
17    /// Insert a stage. Returns `AlreadyExists` if a stage with the same ID is
18    /// already present.
19    async fn put(&self, stage: Stage) -> Result<StageId, StoreError>;
20
21    /// Insert or replace a stage unconditionally.
22    async fn upsert(&self, stage: Stage) -> Result<StageId, StoreError>;
23
24    /// Remove a stage entirely. Succeeds even if the stage does not exist.
25    async fn remove(&self, id: &StageId) -> Result<(), StoreError>;
26
27    /// Retrieve a stage by ID, returning `None` if absent.
28    async fn get(&self, id: &StageId) -> Result<Option<Stage>, StoreError>;
29
30    /// Return true if a stage with the given ID exists.
31    async fn contains(&self, id: &StageId) -> Result<bool, StoreError>;
32
33    /// List all stages, optionally filtered by lifecycle variant.
34    async fn list(&self, lifecycle: Option<StageLifecycle>) -> Result<Vec<Stage>, StoreError>;
35
36    /// Transition the lifecycle of a stage, enforcing valid transitions.
37    async fn update_lifecycle(
38        &self,
39        id: &StageId,
40        lifecycle: StageLifecycle,
41    ) -> Result<(), StoreError>;
42
43    /// Aggregate statistics across the store.
44    async fn stats(&self) -> Result<StoreStats, StoreError>;
45}