use std::future::Future;
use std::time::Duration;
pub mod memory;
pub(crate) mod metered;
#[cfg(feature = "nats")]
pub mod nats;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Keyspace {
Durable,
Ephemeral,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Revision(pub u64);
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Entry {
pub key: String,
pub value: Vec<u8>,
pub revision: Revision,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[must_use]
pub enum CasOutcome {
Won(Revision),
Lost,
}
impl CasOutcome {
pub fn won(self) -> Option<Revision> {
match self {
CasOutcome::Won(rev) => Some(rev),
CasOutcome::Lost => None,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum WatchEvent {
Put(Entry),
Delete {
key: String,
revision: Revision,
},
SnapshotDone,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum StoreError {
#[error("retryable store error: {0}")]
Retryable(String),
#[error("fatal store error: {0}")]
Fatal(String),
}
pub type WatchStream = futures_util::stream::BoxStream<'static, Result<WatchEvent, StoreError>>;
pub trait CoordinationStore: Send + Sync + 'static {
fn lease_ttl(&self) -> Duration;
fn create(
&self,
ks: Keyspace,
key: &str,
value: Vec<u8>,
) -> impl Future<Output = Result<CasOutcome, StoreError>> + Send;
fn update(
&self,
ks: Keyspace,
key: &str,
value: Vec<u8>,
expected: Revision,
) -> impl Future<Output = Result<CasOutcome, StoreError>> + Send;
fn get(
&self,
ks: Keyspace,
key: &str,
) -> impl Future<Output = Result<Option<Entry>, StoreError>> + Send;
fn delete(
&self,
ks: Keyspace,
key: &str,
expected: Option<Revision>,
) -> impl Future<Output = Result<CasOutcome, StoreError>> + Send;
fn watch(
&self,
ks: Keyspace,
prefix: &str,
) -> impl Future<Output = Result<WatchStream, StoreError>> + Send;
fn list(
&self,
ks: Keyspace,
prefix: &str,
) -> impl Future<Output = Result<Vec<Entry>, StoreError>> + Send;
}