feat(sched): ✨ logging
This commit is contained in:
parent
2d3fcbaabd
commit
b880e452a4
@ -28,7 +28,7 @@ path = "lib/lib.rs"
|
|||||||
# macros
|
# macros
|
||||||
"macros" = []
|
"macros" = []
|
||||||
# scheduling
|
# scheduling
|
||||||
"sched" = ["dep:chrono", "utils.threads"]
|
"sched" = ["dep:chrono", "dep:log"]
|
||||||
"sched.tokio" = ["dep:tokio", "tokio?/time", "tokio?/rt", "sched"]
|
"sched.tokio" = ["dep:tokio", "tokio?/time", "tokio?/rt", "sched"]
|
||||||
"sched.rule-recurrence" = ["sched"]
|
"sched.rule-recurrence" = ["sched"]
|
||||||
"sched.rule-cron" = ["sched"]
|
"sched.rule-cron" = ["sched"]
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
use {
|
use {
|
||||||
eyre::{set_hook, DefaultHandler},
|
eyre::{set_hook, DefaultHandler, Result},
|
||||||
lool::sched::{recur, ruleset, Scheduler},
|
lool::{
|
||||||
|
logger::ConsoleLogger,
|
||||||
|
sched::{recur, ruleset, Scheduler},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn setup_eyre() {
|
fn setup_eyre() {
|
||||||
@ -14,22 +17,20 @@ fn my_action() {
|
|||||||
std::thread::sleep(std::time::Duration::from_secs(15));
|
std::thread::sleep(std::time::Duration::from_secs(15));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() -> Result<()> {
|
||||||
setup_eyre();
|
setup_eyre();
|
||||||
|
ConsoleLogger::default_setup(log::Level::Trace, "lool::sched::recur")?;
|
||||||
|
|
||||||
let mut sched = Scheduler::new();
|
let mut sched = Scheduler::new();
|
||||||
|
log::debug!("scheduler created");
|
||||||
|
|
||||||
let handler = sched.schedule("test-task", my_action, recur(ruleset().at_second(0)));
|
let handler = sched.schedule("test-task", my_action, recur(ruleset().at_second(0)));
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let is_running = handler.is_running();
|
|
||||||
let last_run = handler.get_last_run();
|
|
||||||
let next_run = handler.get_next_run();
|
|
||||||
let name = handler.name();
|
let name = handler.name();
|
||||||
|
println!("{:?}", handler);
|
||||||
println!("task {name} |--> running: {is_running}, last: {last_run:?}, next: {next_run:?}");
|
|
||||||
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(60));
|
std::thread::sleep(std::time::Duration::from_secs(60));
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use chrono::{DateTime, Local};
|
|||||||
/// - `Once`: runs only at a specific `chrono::DateTime`
|
/// - `Once`: runs only at a specific `chrono::DateTime`
|
||||||
/// - `Repeat`: runs at specific intervals defined by a `RecurrenceRule`
|
/// - `Repeat`: runs at specific intervals defined by a `RecurrenceRule`
|
||||||
/// - `Cron`: runs at specific intervals defined by a cron expression
|
/// - `Cron`: runs at specific intervals defined by a cron expression
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum SchedulingRule {
|
pub enum SchedulingRule {
|
||||||
/// 🧉 » a scheduling rule that makes the task run only once at a specific `chrono::DateTime`
|
/// 🧉 » a scheduling rule that makes the task run only once at a specific `chrono::DateTime`
|
||||||
Once(chrono::DateTime<Local>),
|
Once(chrono::DateTime<Local>),
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use num_traits::PrimInt;
|
|||||||
/// 🧉 » a recurrence rule unit
|
/// 🧉 » a recurrence rule unit
|
||||||
///
|
///
|
||||||
/// represents a single rule unit that can be used to match a value
|
/// represents a single rule unit that can be used to match a value
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Rule<T>
|
pub enum Rule<T>
|
||||||
where
|
where
|
||||||
T: PrimInt,
|
T: PrimInt,
|
||||||
|
|||||||
@ -11,7 +11,7 @@ use {
|
|||||||
/// sets rules that define a certain recurrence behavior
|
/// sets rules that define a certain recurrence behavior
|
||||||
///
|
///
|
||||||
/// use the builder pattern to create a new `RecurrenceRuleSet`
|
/// use the builder pattern to create a new `RecurrenceRuleSet`
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RecurrenceRuleSet {
|
pub struct RecurrenceRuleSet {
|
||||||
/// second of the minute (0..59)
|
/// second of the minute (0..59)
|
||||||
second: Option<Rule<u32>>,
|
second: Option<Rule<u32>>,
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
use std::{
|
use {
|
||||||
|
eyre::{eyre, Result},
|
||||||
|
log::debug,
|
||||||
|
std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, AtomicPtr, Ordering},
|
atomic::{AtomicBool, AtomicPtr, Ordering},
|
||||||
Arc, Mutex,
|
Arc, Mutex,
|
||||||
},
|
},
|
||||||
thread::{self, JoinHandle},
|
thread::{self, JoinHandle},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use eyre::{eyre, Result};
|
|
||||||
|
|
||||||
use {
|
use {
|
||||||
super::SchedulingRule,
|
super::SchedulingRule,
|
||||||
chrono::{DateTime, Local},
|
chrono::{DateTime, Local},
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: add logging (always as debug)
|
|
||||||
|
|
||||||
type Action = Box<dyn FnMut() + Send + Sync + 'static>;
|
type Action = Box<dyn FnMut() + Send + Sync + 'static>;
|
||||||
|
|
||||||
/// 🧉 » a scheduled task
|
/// 🧉 » a scheduled task
|
||||||
@ -138,6 +138,7 @@ impl Scheduler {
|
|||||||
if let Some(task) = task {
|
if let Some(task) = task {
|
||||||
if let Ok(task) = task.lock() {
|
if let Ok(task) = task.lock() {
|
||||||
task.is_stopped.store(true, Ordering::Relaxed);
|
task.is_stopped.store(true, Ordering::Relaxed);
|
||||||
|
debug!("task {} has been stopped", handler.name());
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(eyre!("error stopping task {}", handler.name()))
|
Err(eyre!("error stopping task {}", handler.name()))
|
||||||
@ -155,6 +156,7 @@ impl Scheduler {
|
|||||||
if let Some(task) = task {
|
if let Some(task) = task {
|
||||||
if let Ok(task) = task.lock() {
|
if let Ok(task) = task.lock() {
|
||||||
task.is_stopped.store(false, Ordering::Relaxed);
|
task.is_stopped.store(false, Ordering::Relaxed);
|
||||||
|
debug!("task {} has been resumed", handler.name());
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(eyre!("error resuming task {}", handler.name()))
|
Err(eyre!("error resuming task {}", handler.name()))
|
||||||
@ -172,6 +174,7 @@ impl Scheduler {
|
|||||||
if let Some(task) = task {
|
if let Some(task) = task {
|
||||||
if let Ok(task) = &mut task.lock() {
|
if let Ok(task) = &mut task.lock() {
|
||||||
task.is_removed.store(true, Ordering::Relaxed);
|
task.is_removed.store(true, Ordering::Relaxed);
|
||||||
|
debug!("task {} has been removed", handler.name());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -189,7 +192,7 @@ impl Scheduler {
|
|||||||
/// returned by the `Scheduler::schedule` method,
|
/// returned by the `Scheduler::schedule` method,
|
||||||
/// this struct can be used to check and control
|
/// this struct can be used to check and control
|
||||||
/// the status of the task.
|
/// the status of the task.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TaskHandler {
|
pub struct TaskHandler {
|
||||||
name: String,
|
name: String,
|
||||||
rules: Arc<Vec<SchedulingRule>>,
|
rules: Arc<Vec<SchedulingRule>>,
|
||||||
@ -282,16 +285,17 @@ fn spawn_task(task_mutex: Arc<Mutex<ScheduledTask>>) -> JoinHandle<()> {
|
|||||||
if run_date > now {
|
if run_date > now {
|
||||||
// if the next run is in the future, go to bed until then
|
// if the next run is in the future, go to bed until then
|
||||||
let sleep_until = run_date - now;
|
let sleep_until = run_date - now;
|
||||||
println!(
|
debug!(
|
||||||
"task {} will run in {} seconds",
|
"task {} will run in {} seconds",
|
||||||
name,
|
name,
|
||||||
sleep_until.num_seconds()
|
sleep_until.num_seconds()
|
||||||
);
|
);
|
||||||
|
|
||||||
std::thread::sleep(sleep_until.to_std().unwrap());
|
std::thread::sleep(sleep_until.to_std().unwrap());
|
||||||
} else {
|
} else {
|
||||||
// if the next run is in the past, run the task immediately, probably missed the
|
// if the next run is in the past, run the task immediately, probably missed the
|
||||||
// run time for a few nanos
|
// run time for a few nanos
|
||||||
println!("task will run in 0 seconds");
|
debug!("task will run in 0 seconds");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut task = task_mutex.lock().unwrap();
|
let mut task = task_mutex.lock().unwrap();
|
||||||
@ -312,6 +316,8 @@ fn spawn_task(task_mutex: Arc<Mutex<ScheduledTask>>) -> JoinHandle<()> {
|
|||||||
maybe_next_run = None;
|
maybe_next_run = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!("task {} has finished", name);
|
||||||
});
|
});
|
||||||
|
|
||||||
thread
|
thread
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user