use std::collections::VecDeque;
use serde::{Deserialize, Serialize};
use xtalforge_core::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum JobStatus {
Queued,
Running,
Done,
Failed,
Cancelled,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Job {
pub id: u64,
pub module: String,
pub parameters: serde_json::Value,
pub status: JobStatus,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct JobQueue {
jobs: VecDeque<Job>,
next: u64,
}
impl JobQueue {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn submit(&mut self, module: &str, parameters: serde_json::Value) -> Result<u64, Error> {
if module.trim().is_empty() {
return Err(Error::InvalidInput("a job needs a module name".to_owned()));
}
let id = self.next;
self.next += 1;
self.jobs.push_back(Job {
id,
module: module.to_owned(),
parameters,
status: JobStatus::Queued,
});
Ok(id)
}
pub fn start_next(&mut self) -> Option<Job> {
let mut job = self.jobs.pop_front()?;
job.status = JobStatus::Running;
self.jobs.push_back(job.clone());
Some(job)
}
pub fn finish(&mut self, id: u64) -> bool {
self.set_status(id, JobStatus::Done)
}
pub fn fail(&mut self, id: u64) -> bool {
self.set_status(id, JobStatus::Failed)
}
pub fn cancel(&mut self, id: u64) -> bool {
self.set_status(id, JobStatus::Cancelled)
}
#[must_use]
pub fn jobs(&self) -> Vec<&Job> {
self.jobs.iter().collect()
}
fn set_status(&mut self, id: u64, status: JobStatus) -> bool {
if let Some(job) = self.jobs.iter_mut().find(|job| job.id == id) {
job.status = status;
true
} else {
false
}
}
}