use std::sync::Arc;
use std::time::Duration;
use crate::error::CacheError;
use crate::governor::Governor;
use crate::policy::CachePolicy;
#[derive(Debug)]
pub struct GovernorHandle {
abort: tokio::task::AbortHandle,
join: tokio::task::JoinHandle<()>,
interval: Duration,
}
impl GovernorHandle {
pub fn abort(&self) {
self.abort.abort();
}
#[must_use]
pub const fn interval(&self) -> Duration {
self.interval
}
pub async fn join(self) {
let _ = self.join.await;
}
}
pub fn spawn<K, V, P>(governor: Arc<Governor<K, V, P>>) -> Result<GovernorHandle, CacheError>
where
K: crate::key::Key + 'static,
V: Clone + Send + Sync + 'static,
P: CachePolicy<K, V> + 'static,
{
if governor.settings().mode != crate::governor::GovernorMode::FullyAutonomous {
return Err(CacheError::ConfigurationError);
}
let interval = governor.settings().interval.max(Duration::from_millis(1));
let handle = tokio::spawn(async move {
loop {
tokio::time::sleep(interval).await;
if let Err(err) = governor.tick().await {
let _ = err;
}
}
});
Ok(GovernorHandle {
abort: handle.abort_handle(),
join: handle,
interval,
})
}