use crate::persistence::{
persistence_id::PersistenceId, schema_version::SchemaVersion, seq_no::SeqNo,
};
use std::{convert::Infallible, error::Error, num::NonZeroUsize};
use thiserror::Error;
use tracing::warn;
#[trait_variant::make(Send)]
pub trait EventStore
where
Self: Clone + Send + Sync + 'static,
{
type Error: Error + Send + Sync + 'static;
async fn append(
&self,
id: &PersistenceId,
next_seq_no: SeqNo,
events: Vec<EncodedEvent>,
) -> Result<(), AppendError<Self::Error>>;
async fn read(
&self,
id: &PersistenceId,
from_seq_no: SeqNo,
limit: NonZeroUsize,
) -> Result<Vec<StoredEvent>, Self::Error>;
}
#[trait_variant::make(Send)]
pub trait SnapshotStore
where
Self: Clone + Send + Sync + 'static,
{
type Error: Error + Send + Sync + 'static;
async fn save(
&self,
id: &PersistenceId,
next_seq_no: SeqNo,
snapshot: EncodedSnapshot,
) -> Result<(), Self::Error>;
async fn load(&self, id: &PersistenceId) -> Result<Option<StoredSnapshot>, Self::Error>;
}
#[derive(Debug, Default, Clone, Copy)]
pub struct NoSnapshots;
impl SnapshotStore for NoSnapshots {
type Error = Infallible;
async fn save(
&self,
id: &PersistenceId,
next_seq_no: SeqNo,
_snapshot: EncodedSnapshot,
) -> Result<(), Self::Error> {
warn!(%id, %next_seq_no, "snapshot dropped, no snapshot store configured");
Ok(())
}
async fn load(&self, _id: &PersistenceId) -> Result<Option<StoredSnapshot>, Self::Error> {
Ok(None)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EncodedEvent {
pub manifest: String,
pub schema_version: SchemaVersion,
pub payload: Vec<u8>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StoredEvent {
pub seq_no: SeqNo,
pub event: EncodedEvent,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EncodedSnapshot {
pub manifest: String,
pub schema_version: SchemaVersion,
pub payload: Vec<u8>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StoredSnapshot {
pub next_seq_no: SeqNo,
pub snapshot: EncodedSnapshot,
}
#[derive(Debug, Error)]
pub enum AppendError<E>
where
E: Error,
{
#[error("append at a stale next sequence number")]
Conflict,
#[error(transparent)]
Store(#[from] E),
}