use crate::job::{Job, QueuedJob};
#[derive(Debug, Clone, PartialEq)]
pub struct Chain {
pub id: String,
steps: Vec<QueuedJob>,
}
impl Chain {
pub fn new<J: Job>(first: J) -> Chain {
Chain { id: chain_id(), steps: vec![first.to_queued()] }
}
pub fn named(mut self, id: impl Into<String>) -> Chain {
self.id = id.into();
self
}
pub fn then<J: Job>(mut self, next: J) -> Chain {
self.steps.push(next.to_queued());
self
}
pub fn then_queued(mut self, next: QueuedJob) -> Chain {
self.steps.push(next);
self
}
pub fn len(&self) -> usize {
self.steps.len()
}
pub fn is_empty(&self) -> bool {
self.steps.is_empty()
}
pub fn into_queued(mut self) -> QueuedJob {
let mut first = self.steps.remove(0);
first.chain = Some(self.id);
first.then = self.steps;
first
}
}
fn chain_id() -> String {
static COUNTER: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
let count = COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
format!("{:x}-{count:x}", crate::time::unix_now())
}
impl QueuedJob {
pub fn next_in_chain(&self) -> Option<QueuedJob> {
let mut rest = self.then.clone();
if rest.is_empty() {
return None;
}
let mut next = rest.remove(0);
next.chain = self.chain.clone();
next.then = rest;
Some(next)
}
}