xtalforge_modules/
jobs.rs1use std::collections::VecDeque;
4
5use serde::{Deserialize, Serialize};
6use xtalforge_core::Error;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
10pub enum JobStatus {
11 Queued,
13 Running,
15 Done,
17 Failed,
19 Cancelled,
21}
22
23#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
25pub struct Job {
26 pub id: u64,
28 pub module: String,
30 pub parameters: serde_json::Value,
32 pub status: JobStatus,
34}
35
36#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
38pub struct JobQueue {
39 jobs: VecDeque<Job>,
40 next: u64,
41}
42
43impl JobQueue {
44 #[must_use]
46 pub fn new() -> Self {
47 Self::default()
48 }
49
50 pub fn submit(&mut self, module: &str, parameters: serde_json::Value) -> Result<u64, Error> {
56 if module.trim().is_empty() {
57 return Err(Error::InvalidInput("a job needs a module name".to_owned()));
58 }
59 let id = self.next;
60 self.next += 1;
61 self.jobs.push_back(Job {
62 id,
63 module: module.to_owned(),
64 parameters,
65 status: JobStatus::Queued,
66 });
67 Ok(id)
68 }
69
70 pub fn start_next(&mut self) -> Option<Job> {
72 let mut job = self.jobs.pop_front()?;
73 job.status = JobStatus::Running;
74 self.jobs.push_back(job.clone());
75 Some(job)
76 }
77
78 pub fn finish(&mut self, id: u64) -> bool {
80 self.set_status(id, JobStatus::Done)
81 }
82
83 pub fn fail(&mut self, id: u64) -> bool {
85 self.set_status(id, JobStatus::Failed)
86 }
87
88 pub fn cancel(&mut self, id: u64) -> bool {
90 self.set_status(id, JobStatus::Cancelled)
91 }
92
93 #[must_use]
95 pub fn jobs(&self) -> Vec<&Job> {
96 self.jobs.iter().collect()
97 }
98
99 fn set_status(&mut self, id: u64, status: JobStatus) -> bool {
100 if let Some(job) = self.jobs.iter_mut().find(|job| job.id == id) {
101 job.status = status;
102 true
103 } else {
104 false
105 }
106 }
107}