use alloc::{string::String, vec::Vec};
use core::time::Duration;
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
use crate::{TaskId, AgentId, Capability};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TaskPriority {
Low = 0,
Normal = 1,
High = 2,
Critical = 3,
}
impl Default for TaskPriority {
fn default() -> Self {
TaskPriority::Normal
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TaskStatus {
Pending,
Scheduled,
Running,
Completed,
Failed,
Cancelled,
Timeout,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Task {
pub id: TaskId,
pub name: String,
pub priority: TaskPriority,
pub required_capabilities: Vec<String>,
pub preferred_agent: Option<AgentId>,
pub dependencies: Vec<TaskId>,
pub payload: Vec<u8>,
pub timeout: Duration,
pub metadata: TaskMetadata,
pub status: TaskStatus,
pub assigned_agent: Option<AgentId>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TaskMetadata {
pub created_at: u64,
pub scheduled_at: Option<u64>,
pub started_at: Option<u64>,
pub completed_at: Option<u64>,
pub resource_estimate: crate::ResourceRequirements,
pub category: String,
}
impl Default for TaskMetadata {
fn default() -> Self {
static mut COUNTER: u64 = 0;
let timestamp = unsafe {
COUNTER += 1;
COUNTER
};
Self {
created_at: timestamp,
scheduled_at: None,
started_at: None,
completed_at: None,
resource_estimate: crate::ResourceRequirements::default(),
category: "generic".into(),
}
}
}
impl Task {
pub fn new(name: String, payload: Vec<u8>) -> Self {
Self {
id: TaskId::new(),
name,
priority: TaskPriority::Normal,
required_capabilities: Vec::new(),
preferred_agent: None,
dependencies: Vec::new(),
payload,
timeout: Duration::from_secs(300), metadata: TaskMetadata::default(),
status: TaskStatus::Pending,
assigned_agent: None,
}
}
pub fn with_priority(mut self, priority: TaskPriority) -> Self {
self.priority = priority;
self
}
pub fn with_capability(mut self, capability: String) -> Self {
self.required_capabilities.push(capability);
self
}
pub fn with_preferred_agent(mut self, agent_id: AgentId) -> Self {
self.preferred_agent = Some(agent_id);
self
}
pub fn with_dependency(mut self, task_id: TaskId) -> Self {
self.dependencies.push(task_id);
self
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
pub fn with_category(mut self, category: String) -> Self {
self.metadata.category = category;
self
}
pub fn schedule(&mut self, agent_id: AgentId) {
self.status = TaskStatus::Scheduled;
self.assigned_agent = Some(agent_id);
static mut COUNTER: u64 = 0;
self.metadata.scheduled_at = Some(unsafe {
COUNTER += 1;
COUNTER
});
}
pub fn start(&mut self) {
self.status = TaskStatus::Running;
static mut COUNTER: u64 = 0;
self.metadata.started_at = Some(unsafe {
COUNTER += 1;
COUNTER
});
}
pub fn complete(&mut self) {
self.status = TaskStatus::Completed;
static mut COUNTER: u64 = 0;
self.metadata.completed_at = Some(unsafe {
COUNTER += 1;
COUNTER
});
}
pub fn fail(&mut self) {
self.status = TaskStatus::Failed;
static mut COUNTER: u64 = 0;
self.metadata.completed_at = Some(unsafe {
COUNTER += 1;
COUNTER
});
}
pub fn cancel(&mut self) {
self.status = TaskStatus::Cancelled;
static mut COUNTER: u64 = 0;
self.metadata.completed_at = Some(unsafe {
COUNTER += 1;
COUNTER
});
}
pub fn is_ready(&self, completed_tasks: &[TaskId]) -> bool {
if self.status != TaskStatus::Pending {
return false;
}
self.dependencies.iter().all(|dep| completed_tasks.contains(dep))
}
pub fn execution_duration(&self) -> Option<u64> {
match (self.metadata.started_at, self.metadata.completed_at) {
(Some(start), Some(end)) => Some(end - start),
_ => None,
}
}
pub fn total_duration(&self) -> Option<u64> {
self.metadata.completed_at.map(|end| end - self.metadata.created_at)
}
}
pub struct TaskBuilder {
task: Task,
}
impl TaskBuilder {
pub fn new(name: String) -> Self {
Self {
task: Task::new(name, Vec::new()),
}
}
pub fn payload(mut self, payload: Vec<u8>) -> Self {
self.task.payload = payload;
self
}
pub fn priority(mut self, priority: TaskPriority) -> Self {
self.task.priority = priority;
self
}
pub fn requires(mut self, capability: String) -> Self {
self.task.required_capabilities.push(capability);
self
}
pub fn prefer_agent(mut self, agent_id: AgentId) -> Self {
self.task.preferred_agent = Some(agent_id);
self
}
pub fn depends_on(mut self, task_id: TaskId) -> Self {
self.task.dependencies.push(task_id);
self
}
pub fn timeout(mut self, timeout: Duration) -> Self {
self.task.timeout = timeout;
self
}
pub fn category(mut self, category: String) -> Self {
self.task.metadata.category = category;
self
}
pub fn build(self) -> Task {
self.task
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TaskResult {
pub task_id: TaskId,
pub agent_id: AgentId,
pub status: TaskStatus,
pub result: Vec<u8>,
pub error: Option<String>,
pub metrics: TaskMetrics,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TaskMetrics {
pub queue_time: u64,
pub execution_time: u64,
pub total_time: u64,
pub memory_used: u64,
pub cpu_cycles: u64,
}
impl TaskResult {
pub fn success(task_id: TaskId, agent_id: AgentId, result: Vec<u8>, metrics: TaskMetrics) -> Self {
Self {
task_id,
agent_id,
status: TaskStatus::Completed,
result,
error: None,
metrics,
}
}
pub fn failure(task_id: TaskId, agent_id: AgentId, error: String, metrics: TaskMetrics) -> Self {
Self {
task_id,
agent_id,
status: TaskStatus::Failed,
result: Vec::new(),
error: Some(error),
metrics,
}
}
}