mod backoff;
pub use backoff::BackoffPolicy;
use crate::error::CanoResult;
use crate::workflow::Workflow;
use chrono::{DateTime, Utc};
use cron::Schedule as CronSchedule;
use std::hash::Hash;
use std::sync::Arc;
use tokio::sync::{RwLock, oneshot};
use tokio::time::Duration;
enum SchedulerCommand {
Stop,
Trigger {
id: String,
response: oneshot::Sender<CanoResult<()>>,
},
Reset {
id: String,
response: oneshot::Sender<CanoResult<()>>,
},
}
#[derive(Debug, Clone)]
pub enum Schedule {
Every(Duration),
Cron(String),
Manual,
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum Status {
Idle,
Running,
Completed,
Backoff {
until: DateTime<Utc>,
streak: u32,
last_error: String,
},
Tripped {
streak: u32,
last_error: String,
},
}
#[derive(Debug, Clone)]
pub struct FlowInfo {
pub id: String,
pub status: Status,
pub run_count: u64,
pub last_run: Option<DateTime<Utc>>,
pub failure_streak: u32,
pub next_eligible: Option<DateTime<Utc>>,
}
#[derive(Clone)]
enum ParsedSchedule {
Every(Duration),
Cron(Box<CronSchedule>),
Manual,
}
struct FlowData<TState, TResourceKey>
where
TState: Clone + Send + Sync + 'static + std::fmt::Debug + std::hash::Hash + Eq,
TResourceKey: Hash + Eq + Send + Sync + 'static,
{
workflow: Arc<Workflow<TState, TResourceKey>>,
initial_state: TState,
schedule: ParsedSchedule,
info: Arc<RwLock<FlowInfo>>,
policy: Arc<BackoffPolicy>,
}
impl<TState, TResourceKey> Clone for FlowData<TState, TResourceKey>
where
TState: Clone + Send + Sync + 'static + std::fmt::Debug + std::hash::Hash + Eq,
TResourceKey: Hash + Eq + Send + Sync + 'static,
{
fn clone(&self) -> Self {
Self {
workflow: Arc::clone(&self.workflow),
initial_state: self.initial_state.clone(),
schedule: self.schedule.clone(),
info: Arc::clone(&self.info),
policy: self.policy.clone(),
}
}
}
mod builder;
mod loops;
mod running;
#[cfg(test)]
mod test_support;
pub use builder::Scheduler;
pub use running::RunningScheduler;