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" = []
# scheduling
"sched" = ["dep:chrono", "utils.threads"]
"sched" = ["dep:chrono", "dep:log"]
"sched.tokio" = ["dep:tokio", "tokio?/time", "tokio?/rt", "sched"]
"sched.rule-recurrence" = ["sched"]
"sched.rule-cron" = ["sched"]

View File

@ -1,6 +1,9 @@
use {
eyre::{set_hook, DefaultHandler},
lool::sched::{recur, ruleset, Scheduler},
eyre::{set_hook, DefaultHandler, Result},
lool::{
logger::ConsoleLogger,
sched::{recur, ruleset, Scheduler},
},
};
fn setup_eyre() {
@ -14,22 +17,20 @@ fn my_action() {
std::thread::sleep(std::time::Duration::from_secs(15));
}
fn main() {
fn main() -> Result<()> {
setup_eyre();
ConsoleLogger::default_setup(log::Level::Trace, "lool::sched::recur")?;
let mut sched = Scheduler::new();
log::debug!("scheduler created");
let handler = sched.schedule("test-task", my_action, recur(ruleset().at_second(0)));
std::thread::sleep(std::time::Duration::from_secs(1));
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();
println!("task {name} |--> running: {is_running}, last: {last_run:?}, next: {next_run:?}");
println!("{:?}", handler);
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`
/// - `Repeat`: runs at specific intervals defined by a `RecurrenceRule`
/// - `Cron`: runs at specific intervals defined by a cron expression
#[derive(Clone)]
#[derive(Clone, Debug)]
pub enum SchedulingRule {
/// 🧉 » a scheduling rule that makes the task run only once at a specific `chrono::DateTime`
Once(chrono::DateTime<Local>),

View File

@ -3,7 +3,7 @@ use num_traits::PrimInt;
/// 🧉 » a recurrence rule unit
///
/// represents a single rule unit that can be used to match a value
#[derive(Clone)]
#[derive(Clone, Debug)]
pub enum Rule<T>
where
T: PrimInt,

View File

@ -11,7 +11,7 @@ use {
/// sets rules that define a certain recurrence behavior
///
/// use the builder pattern to create a new `RecurrenceRuleSet`
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct RecurrenceRuleSet {
/// second of the minute (0..59)
second: Option<Rule<u32>>,

View File

@ -1,21 +1,21 @@
use std::{
collections::HashMap,
sync::{
atomic::{AtomicBool, AtomicPtr, Ordering},
Arc, Mutex,
use {
eyre::{eyre, Result},
log::debug,
std::{
collections::HashMap,
sync::{
atomic::{AtomicBool, AtomicPtr, Ordering},
Arc, Mutex,
},
thread::{self, JoinHandle},
},
thread::{self, JoinHandle},
};
use eyre::{eyre, Result};
use {
super::SchedulingRule,
chrono::{DateTime, Local},
};
// TODO: add logging (always as debug)
type Action = Box<dyn FnMut() + Send + Sync + 'static>;
/// 🧉 » a scheduled task
@ -138,6 +138,7 @@ impl Scheduler {
if let Some(task) = task {
if let Ok(task) = task.lock() {
task.is_stopped.store(true, Ordering::Relaxed);
debug!("task {} has been stopped", handler.name());
Ok(())
} else {
Err(eyre!("error stopping task {}", handler.name()))
@ -155,6 +156,7 @@ impl Scheduler {
if let Some(task) = task {
if let Ok(task) = task.lock() {
task.is_stopped.store(false, Ordering::Relaxed);
debug!("task {} has been resumed", handler.name());
Ok(())
} else {
Err(eyre!("error resuming task {}", handler.name()))
@ -172,6 +174,7 @@ impl Scheduler {
if let Some(task) = task {
if let Ok(task) = &mut task.lock() {
task.is_removed.store(true, Ordering::Relaxed);
debug!("task {} has been removed", handler.name());
Ok(())
} else {
@ -189,7 +192,7 @@ impl Scheduler {
/// returned by the `Scheduler::schedule` method,
/// this struct can be used to check and control
/// the status of the task.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct TaskHandler {
name: String,
rules: Arc<Vec<SchedulingRule>>,
@ -282,16 +285,17 @@ fn spawn_task(task_mutex: Arc<Mutex<ScheduledTask>>) -> JoinHandle<()> {
if run_date > now {
// if the next run is in the future, go to bed until then
let sleep_until = run_date - now;
println!(
debug!(
"task {} will run in {} seconds",
name,
sleep_until.num_seconds()
);
std::thread::sleep(sleep_until.to_std().unwrap());
} else {
// if the next run is in the past, run the task immediately, probably missed the
// 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();
@ -312,6 +316,8 @@ fn spawn_task(task_mutex: Arc<Mutex<ScheduledTask>>) -> JoinHandle<()> {
maybe_next_run = None;
}
}
debug!("task {} has finished", name);
});
thread