use async_trait::async_trait;
use std::sync::Arc;
use super::{ServiceReadyNotifier, ServiceWithDependents};
#[cfg(unix)]
use crate::server::ListenFds;
use crate::server::ShutdownWatch;
#[async_trait]
pub trait BackgroundService {
async fn start_with_ready_notifier(
&self,
shutdown: ShutdownWatch,
ready_notifier: ServiceReadyNotifier,
) {
ready_notifier.notify_ready();
self.start(shutdown).await;
}
async fn start(&self, mut _shutdown: ShutdownWatch) {}
}
pub struct GenBackgroundService<A> {
name: String,
task: Arc<A>,
pub threads: Option<usize>,
}
impl<A> GenBackgroundService<A> {
pub fn new(name: String, task: Arc<A>) -> Self {
Self {
name,
task,
threads: Some(1),
}
}
pub fn task(&self) -> Arc<A> {
self.task.clone()
}
}
#[async_trait]
impl<A> ServiceWithDependents for GenBackgroundService<A>
where
A: BackgroundService + Send + Sync + 'static,
{
async fn start_service(
&mut self,
#[cfg(unix)] _fds: Option<ListenFds>,
shutdown: ShutdownWatch,
_listeners_per_fd: usize,
ready: ServiceReadyNotifier,
) {
self.task.start_with_ready_notifier(shutdown, ready).await;
}
fn name(&self) -> &str {
&self.name
}
fn threads(&self) -> Option<usize> {
self.threads
}
}
pub fn background_service<SV>(name: &str, task: SV) -> GenBackgroundService<SV> {
GenBackgroundService::new(format!("BG {name}"), Arc::new(task))
}