use std::time::{Duration, Instant};
use dope_core::driver::DriverConfig;
use dope_core::profile::Profile;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct IdleParkPolicy {
active_window: Duration,
active_park_timeout: Duration,
idle_park_timeout: Duration,
}
impl IdleParkPolicy {
pub(super) fn from_profile<P: Profile>() -> Self {
Self {
active_window: P::ACTIVE_WINDOW,
active_park_timeout: P::ACTIVE_PARK_TIMEOUT,
idle_park_timeout: P::IDLE_PARK_TIMEOUT,
}
}
pub(super) fn timeout_for(
&self,
now: Instant,
next_deadline: Option<Instant>,
shutdown_deadline: Option<Instant>,
last_activity: Instant,
) -> Option<Duration> {
if let Some(deadline) = shutdown_deadline
&& now >= deadline
{
return None;
}
let base = if now.saturating_duration_since(last_activity) <= self.active_window {
self.active_park_timeout
} else {
self.idle_park_timeout
};
let mut timeout = next_deadline
.map(|d| d.saturating_duration_since(now))
.unwrap_or(base);
if let Some(deadline) = shutdown_deadline {
timeout = timeout.min(deadline.saturating_duration_since(now));
}
if timeout.is_zero() {
Some(Duration::from_micros(1))
} else {
Some(timeout)
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct RuntimeTuning<C: DriverConfig> {
pub(crate) driver: C,
pub(crate) idle_park_policy: IdleParkPolicy,
}
impl<C: DriverConfig> RuntimeTuning<C> {
pub fn for_profile<P: Profile>() -> Self {
Self {
driver: <C as DriverConfig>::for_profile::<P>(),
idle_park_policy: IdleParkPolicy::from_profile::<P>(),
}
}
}