use std::sync::Arc;
use std::time::Duration;
use bytes::Bytes;
use cronoq::{MemoryStore, Store, StoreQueries};
pub struct Opened {
pub store: Arc<dyn Store<Bytes, Bytes>>,
pub queries: Option<Arc<dyn StoreQueries<Bytes>>>,
}
impl Opened {
pub fn memory() -> Opened {
Opened {
store: Arc::new(MemoryStore),
queries: None,
}
}
pub fn durable<S: Store<Bytes, Bytes> + StoreQueries<Bytes> + Clone>(s: S) -> Opened {
Opened {
store: Arc::new(s.clone()),
queries: Some(Arc::new(s)),
}
}
}
pub async fn leadership_lost(queries: Option<Arc<dyn StoreQueries<Bytes>>>) {
match queries {
Some(q) => q.leadership_lost().await,
None => std::future::pending().await,
}
}
pub fn spawn_pruner(
queries: Arc<dyn StoreQueries<Bytes>>,
keep: Duration,
every: Duration,
) -> tokio::task::JoinHandle<()> {
tokio::spawn(async move {
let mut iv = tokio::time::interval(every);
loop {
iv.tick().await;
if !queries.is_leader() {
continue;
}
match queries.prune(keep).await {
Ok(n) if n > 0 => tracing::info!(rows = n, "pruned finished tasks"),
Ok(_) => {}
Err(e) => tracing::warn!(error = %e, "prune failed"),
}
}
})
}