feat(sched): logging

This commit is contained in:
Lucas Colombo 2024-04-11 00:35:31 -03:00
parent 2d3fcbaabd
commit b880e452a4
Signed by: lucas
GPG Key ID: EF34786CFEFFAE35
6 changed files with 32 additions and 25 deletions

View File

@ -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"]

View File

@ -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));

View File

@ -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>),

View File

@ -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,

View File

@ -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>>,

View File

@ -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