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}