use std::future::Future;
use std::pin::Pin;
use crate::builder::BackgroundStrategy;
use crate::builder::TaskFactory;
use crate::builder::strategies::{BackgroundContext, MaintenanceTrigger};
use crate::error::Result;
pub(crate) struct MaintenanceTask {
pub(crate) factory: TaskFactory,
pub(crate) strategy: std::sync::Arc<dyn BackgroundStrategy>,
}
pub(crate) fn spawn_tasks(
tasks: Vec<MaintenanceTask>,
cancellation: tokio_util::sync::CancellationToken,
) -> Result<()> {
let (tx, mut rx) = tokio::sync::mpsc::channel::<Pin<Box<dyn Future<Output = ()> + Send>>>(16);
let cancel_clone = cancellation.clone();
tokio::spawn(async move {
loop {
tokio::select! {
maybe_task = rx.recv() => {
match maybe_task {
Some(task) => task.await,
None => break, }
}
_ = cancel_clone.cancelled() => {
break; }
}
}
});
for task in tasks {
let trigger = MaintenanceTrigger::new(tx.clone(), task.factory);
let ctx = BackgroundContext::new(trigger, cancellation.clone());
task.strategy.schedule(ctx)?;
}
Ok(())
}