use std::collections::HashSet;
use aion_core::{Event, WorkflowId};
use aion_store::EventStore;
use crate::EngineError;
pub(super) async fn list_recoverable(
store: &dyn EventStore,
) -> Result<Vec<WorkflowId>, EngineError> {
let started = std::time::Instant::now();
let mut recoverable = store.list_active().await?;
recoverable.extend(store.list_paused().await?);
let mut seen = HashSet::new();
recoverable.retain(|workflow_id| seen.insert(workflow_id.clone()));
tracing::info!(
candidates = recoverable.len(),
elapsed_ms = elapsed_ms(started),
"startup recovery: in-flight workflows listed"
);
Ok(recoverable)
}
pub(super) struct ReplayTally {
started: std::time::Instant,
histories_read: usize,
events_read: usize,
}
impl ReplayTally {
pub(super) fn start() -> Self {
Self {
started: std::time::Instant::now(),
histories_read: 0,
events_read: 0,
}
}
pub(super) fn record(&mut self, workflow_id: &WorkflowId, history: &[Event]) {
self.histories_read += 1;
self.events_read += history.len();
tracing::debug!(
workflow_id = %workflow_id,
events = history.len(),
"startup recovery: history read"
);
}
}
impl Drop for ReplayTally {
fn drop(&mut self) {
tracing::info!(
histories_read = self.histories_read,
events_read = self.events_read,
elapsed_ms = elapsed_ms(self.started),
"startup recovery: resident workflows repopulated"
);
}
}
pub(crate) fn elapsed_ms(started: std::time::Instant) -> u64 {
u64::try_from(started.elapsed().as_millis()).unwrap_or(u64::MAX)
}