use crate::error::ExecutorResult;
use crate::platform::Instant;
use crate::{Priority, TaskId};
pub trait TaskManager: Send + Sync + 'static {
fn cancel_task(&self, id: TaskId) -> ExecutorResult<()>;
fn task_status(&self, id: TaskId) -> Option<TaskStatus>;
fn wait_for_task(
&self,
id: TaskId,
timeout: Option<core::time::Duration>,
) -> impl core::future::Future<Output = ExecutorResult<()>> + Send;
fn task_stats(&self, id: TaskId) -> Option<TaskStats>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TaskStatus {
Queued,
Running,
Completed,
Cancelled,
Failed,
}
impl core::fmt::Display for TaskStatus {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Queued => write!(f, "Queued"),
Self::Running => write!(f, "Running"),
Self::Completed => write!(f, "Completed"),
Self::Cancelled => write!(f, "Cancelled"),
Self::Failed => write!(f, "Failed"),
}
}
}
#[derive(Debug, Clone)]
pub struct TaskStats {
pub id: TaskId,
pub status: TaskStatus,
pub priority: Priority,
pub spawn_time: Instant,
pub start_time: Option<Instant>,
pub completion_time: Option<Instant>,
pub cpu_time_ns: u64,
}
impl TaskStats {
#[must_use]
pub fn execution_time(&self) -> Option<core::time::Duration> {
match (&self.start_time, &self.completion_time) {
(Some(start), Some(end)) => Some(end.duration_since(*start)),
_ => None,
}
}
#[must_use]
pub fn queue_time(&self) -> Option<core::time::Duration> {
match &self.start_time {
Some(start) => Some(start.duration_since(self.spawn_time)),
None => Some(Instant::now().duration_since(self.spawn_time)),
}
}
#[must_use]
pub fn is_active(&self) -> bool {
matches!(self.status, TaskStatus::Queued | TaskStatus::Running)
}
#[must_use]
pub fn is_finished(&self) -> bool {
matches!(
self.status,
TaskStatus::Completed | TaskStatus::Cancelled | TaskStatus::Failed
)
}
}