use std::time::{Duration, SystemTime};
use async_trait::async_trait;
use cronoq_core::{Mutation, Priority, Recovered, TaskId, TaskRef, TaskStatus};
use crate::error::StoreError;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct TimeBase {
pub unix_nanos_at_zero: i64,
}
#[async_trait]
pub trait Store<P, O>: Send + Sync + 'static {
fn persists(&self) -> bool {
true
}
async fn acquire_leadership(&self) -> Result<u16, StoreError>;
async fn release_leadership(&self) {}
async fn commit(
&self,
epoch: u16,
base: TimeBase,
batch: &[Mutation<P>],
outputs: &[(TaskId, &O)],
) -> Result<(), StoreError>;
async fn recover(&self, base: TimeBase) -> Result<Recovered<P>, StoreError>;
async fn load_output(&self, _id: TaskId) -> Result<Option<O>, StoreError> {
Ok(None)
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct TaskRecord<O> {
pub id: TaskId,
pub key: Option<String>,
pub pool: String,
pub kind: String,
pub priority: Priority,
pub tenant: Option<String>,
pub status: Option<TaskStatus>,
pub attempt: u32,
pub message: Option<String>,
pub output: Option<O>,
pub updated: SystemTime,
}
#[async_trait]
pub trait StoreQueries<O>: Send + Sync + 'static {
async fn get_task(&self, target: &TaskRef) -> Result<Option<TaskRecord<O>>, StoreError>;
async fn prune(&self, older_than: Duration) -> Result<u64, StoreError>;
async fn list_finished(
&self,
pools: &[&str],
statuses: &[TaskStatus],
after: Option<TaskId>,
limit: usize,
) -> Result<Vec<TaskRecord<O>>, StoreError>;
fn is_leader(&self) -> bool;
async fn leadership_lost(&self);
}
#[derive(Clone, Copy, Debug, Default)]
pub struct MemoryStore;
#[async_trait]
impl<P: Send + Sync + 'static, O: Send + Sync + 'static> Store<P, O> for MemoryStore {
fn persists(&self) -> bool {
false
}
async fn acquire_leadership(&self) -> Result<u16, StoreError> {
Ok(0)
}
async fn commit(
&self,
_: u16,
_: TimeBase,
_: &[Mutation<P>],
_: &[(TaskId, &O)],
) -> Result<(), StoreError> {
Ok(())
}
async fn recover(&self, _: TimeBase) -> Result<Recovered<P>, StoreError> {
Ok(Recovered::default())
}
}