use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum CommitMode {
MemoryOnly,
AsyncDurable { group_window_ms: u32 },
SyncDurable,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PersistOptions {
pub commit_mode: CommitMode,
pub snapshot_every_n_events: u32,
pub snapshot_every_bytes: u64,
pub snapshot_every_ms: u64,
pub compression: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PersistedEvent {
pub lsn: i64,
pub tr_id: u64,
pub doc_id: String,
pub ts: i64,
pub actor: Option<String>,
pub idempotency_key: String,
pub payload: Vec<u8>,
pub meta: serde_json::Value,
pub checksum: u32,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Snapshot {
pub doc_id: String,
pub upto_lsn: i64,
pub created_at: i64,
pub state_blob: Vec<u8>,
pub version: i32,
}
#[async_trait]
pub trait EventStore: Send + Sync {
async fn append(
&self,
ev: PersistedEvent,
) -> anyhow::Result<i64>;
async fn append_batch(
&self,
evs: Vec<PersistedEvent>,
) -> anyhow::Result<i64>;
async fn load_since(
&self,
doc_id: &str,
from_lsn: i64,
limit: u32,
) -> anyhow::Result<Vec<PersistedEvent>>;
async fn latest_snapshot(
&self,
doc_id: &str,
) -> anyhow::Result<Option<Snapshot>>;
async fn write_snapshot(
&self,
snap: Snapshot,
) -> anyhow::Result<()>;
async fn compact(
&self,
doc_id: &str,
) -> anyhow::Result<()>;
}
#[derive(Clone, Debug)]
pub struct LoadedState {
pub upto_lsn: i64,
pub snapshot: Option<Snapshot>,
pub events: Vec<PersistedEvent>,
}
#[async_trait]
pub trait Persistence: Send + Sync {
async fn persist_transaction(
&self,
tr: &mf_state::Transaction,
doc_id: &str,
context_meta: &serde_json::Value,
) -> anyhow::Result<i64>;
async fn load_state(
&self,
doc_id: &str,
) -> anyhow::Result<LoadedState>;
async fn checkpoint_if_needed(
&self,
doc_id: &str,
) -> anyhow::Result<()>;
}