Crate rucron

Source
Expand description

Rucron is a lightweight job scheduler, it is similar to gocron or linux crontab, and it is very easy to use. Now rucron is compatible with the smol and tokio.

§Usage

Add this to your Cargo.toml

[dependencies]
# PICK ONE OF THE FOLLOWING:
# tokio
rucron = { version = "0.1.5", features = [ "tokio" ] }
# smol
rucron = { version = "0.1.5", features = [ "smol" ] }

Quick start:


use rucron::{execute, sync_execute, EmptyTask, Metric, Scheduler};
use std::{error::Error, sync::atomic::Ordering};
use chrono::{Local, DateTime, Duration};


async fn foo() -> Result<(), Box<dyn Error>>{
    println!("foo");
    Ok(())
}

async fn bar() -> Result<(), Box<dyn Error>>{
    println!("bar");
    Ok(())
}

async fn ping() -> Result<(), Box<dyn Error>>{
    println!("ping");
    Ok(())
}

fn sync_task() -> Result<(), Box<dyn Error>>{
    std::thread::sleep(std::time::Duration::from_secs(2));
    println!("sync");
    Ok(())
}

fn once(m: &Metric, last: &DateTime<Local>) -> Duration {
    let n = m.n_scheduled.load(Ordering::Relaxed);
    if n < 1 {
        Duration::seconds(2)
    } else if n == 1 {
        Duration::seconds(last.timestamp() * 2)
    } else {
        Duration::seconds(0)
   }
}




#[tokio::main]
async fn main(){
    // Create a scheduler with 10 capacity, it will checkout all runnable jobs every second
    let sch = Scheduler::<EmptyTask, ()>::new(1, 10);
    let sch = sch
                // Scheduler runs foo every second.
                .every(1).second().todo(execute(foo)).await
                // Scheduler runs bar every monday at 9 am.
                .at().week(1, 9, 0, 0).todo(execute(bar)).await
                // Scheduler runs ping only once.
                .by(once).todo(execute(ping)).await
                // Scheduler a CPU-bound or blocking task.
                .every(2).second().todo(sync_execute(sync_task)).await
                // Schedule a CPU-bound or blocking task.
                .every(2).second().todo(sync_execute(sync_task)).await;
    // Start running all jobs.
    // sch.start().await;
}

/*
If you use the smol feature:
fn main(){
    let sch = Scheduler::<EmptyTask, ()>::new(1, 10);
    smol::block_on(async move {
        let sch = sch.every(2).second().todo(execute(ping)).await;
        sch.start().await;
    });
}
*/

Schedule parameterized job.


use rucron::{execute, ArgStorage, EmptyTask, ParseArgs, Scheduler};
use std::error::Error;
use async_trait::async_trait;


#[derive(Clone)]
struct Person {
    age: i32,
}

#[async_trait]
impl ParseArgs for Person {
    type Err = std::io::Error;
    fn parse_args(args: &ArgStorage) -> Result<Self, Self::Err> {
        return Ok(args.get::<Person>().unwrap().clone());
    }
}

async fn is_eight_years_old(p: Person) -> Result<(), Box<dyn Error>> {
    if p.age == 8 {
        println!("I am eight years old!");
    } else {
        println!("Oops!");
    };
    Ok(())
}

#[tokio::main]
async fn main() {
    let child = Person { age: 8 };
    // Storage stores all arguments.
    let mut arg = ArgStorage::new();
    arg.insert(child);
    let mut sch = Scheduler::<EmptyTask, ()>::new(1, 10);
    sch.set_arg_storage(arg);
    let sch = sch.every(2).second().todo(execute(is_eight_years_old)).await;
    // sch.start().await;
}

You could also schedule blocking or CPU-bound tasks.

use rucron::{sync_execute, ArgStorage, EmptyTask, ParseArgs, Scheduler};
use std::error::Error;


#[derive(Clone)]
struct Person {
    age: i32,
}

impl ParseArgs for Person {
    type Err = std::io::Error;
    fn parse_args(args: &ArgStorage) -> Result<Self, Self::Err> {
        return Ok(args.get::<Person>().unwrap().clone());
    }
}

fn sync_set_age(p: Person) -> Result<(), Box<dyn Error>> {
    if p.age == 8 {
        println!("I am eight years old!");
    };
    Ok(())
}

#[tokio::main]
async fn main() {
    let child = Person { age: 8 };
    let mut arg = ArgStorage::new();
    arg.insert(child);
    let mut sch = Scheduler::<EmptyTask, ()>::new(1, 10);
    sch.set_arg_storage(arg);
    let sch = sch.every(2).second().todo(sync_execute(sync_set_age)).await;
    //sch.start().await;
}

Re-exports§

pub use crate::error::RucronError;
pub use crate::handler::execute;
pub use crate::handler::sync_execute;
pub use crate::handler::ArgStorage;
pub use crate::handler::ParseArgs;
pub use crate::locker::Locker;
pub use crate::metric::Metric;
pub use crate::scheduler::EmptyTask;
pub use crate::scheduler::Scheduler;

Modules§

error
handler
locker
metric
scheduler

Structs§

RwLock
An asynchronous reader-writer lock.
Sender
Sends values to the associated Receiver.

Functions§

channel
get_metric_with_name
Get the Metric data and serialize it to String, return NotFound error if can not find the metric with name.
sleep
spawn