use std::{fmt::Debug, sync::Arc};
use tracing::Instrument;
use crate::{GraftErr, local::fjall_storage::FjallStorage, remote::Remote};
pub mod autosync;
pub type Result<T> = culprit::Result<T, GraftErr>;
pub trait Task: Debug {
const NAME: &'static str;
async fn run(&mut self, storage: &FjallStorage, remote: &Remote) -> Result<()>;
#[allow(unused_variables)]
fn should_restart(&self, err: &GraftErr) -> bool {
true
}
}
pub async fn supervise<T: Task>(
storage: Arc<FjallStorage>,
remote: Arc<Remote>,
mut task: T,
) -> Result<()> {
for restarts in 0usize.. {
let span = tracing::debug_span!("task", t = T::NAME, r = restarts);
match task.run(&storage, &remote).instrument(span).await {
Ok(()) => {
tracing::debug!("task {:?} completed without error; shutting down", task);
break;
}
Err(err) => {
tracing::error!("task {:?} failed: {:?}", task, err);
if !task.should_restart(err.ctx()) {
return Err(err);
}
}
}
tracing::debug!("restarting task {:?}", task);
}
Ok(())
}