You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.2 KiB
91 lines
2.2 KiB
use crate::{models::PreparedJob, types::Id, u_runner::IdentifiableFuture}; |
|
use chrono::{DateTime, Utc}; |
|
use core::fmt; |
|
use serde::{Deserialize, Serialize}; |
|
use std::sync::Arc; |
|
|
|
pub trait SchedulerJob { |
|
fn call(&self) -> IdentifiableFuture<()>; |
|
} |
|
|
|
// scheduler job need to be called repeatedly, |
|
// the only way to achieve this is to use Fn() -> Future |
|
impl<F> SchedulerJob for F |
|
where |
|
F: Fn() -> IdentifiableFuture<()>, |
|
{ |
|
fn call(&self) -> IdentifiableFuture<()> { |
|
self() |
|
} |
|
} |
|
|
|
#[derive(Clone)] |
|
pub struct Entry { |
|
pub entry_id: Id, |
|
pub schedule: Option<cron::Schedule>, |
|
pub next: Option<DateTime<Utc>>, |
|
pub runnable: EntryType, |
|
} |
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)] |
|
pub struct EntryStat { |
|
pub entry_id: Id, |
|
pub job_ident: String, |
|
pub schedule: String, |
|
pub next: Option<DateTime<Utc>>, |
|
} |
|
|
|
#[derive(Clone)] |
|
pub enum EntryType { |
|
Common(Arc<dyn SchedulerJob + Send + Sync>), |
|
URunner(PreparedJob), |
|
} |
|
|
|
impl<J: SchedulerJob + Send + Sync + 'static> From<J> for EntryType { |
|
fn from(value: J) -> Self { |
|
Self::Common(Arc::new(value)) |
|
} |
|
} |
|
|
|
impl From<PreparedJob> for EntryType { |
|
fn from(value: PreparedJob) -> Self { |
|
Self::URunner(value) |
|
} |
|
} |
|
|
|
impl Entry { |
|
pub fn set_next_run_time(&mut self) { |
|
self.next = self.get_next_run_time(); |
|
} |
|
|
|
pub fn get_next_run_time(&self) -> Option<DateTime<Utc>> { |
|
match &self.schedule { |
|
Some(schedule) => schedule.upcoming(Utc).next(), |
|
None => Some(Utc::now()), |
|
} |
|
} |
|
|
|
pub fn as_stat(&self) -> EntryStat { |
|
let job_ident = match &self.runnable { |
|
EntryType::URunner(entry) => entry.job.meta.id.to_string(), |
|
EntryType::Common(entry) => entry.call().job_ident.to_string(), |
|
}; |
|
|
|
EntryStat { |
|
entry_id: self.entry_id, |
|
job_ident, |
|
schedule: self |
|
.schedule |
|
.as_ref() |
|
.map(|s| s.to_string()) |
|
.unwrap_or_default(), |
|
next: self.next.clone(), |
|
} |
|
} |
|
} |
|
|
|
impl fmt::Debug for Entry { |
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
write!(f, "{} {:?} {:?}", self.entry_id, self.schedule, self.next) |
|
} |
|
}
|
|
|