7 个版本

0.1.6 2024年3月2日
0.1.5 2023年10月10日
0.1.4 2022年4月1日
0.1.3 2022年3月31日
0.1.1 2021年12月26日

#191并发

每月42次 下载

MIT 许可证

81KB
1.5K SLoC

Rucron:一个纯 Rust 实现的作业调度包。

Crates.io version docs.rs docs Download

Rucron 是一个轻量级的作业调度器,类似于 gocron 或 Linux crontab,并且非常易于使用。现在 rucron 兼容 smoltokio

用法

将以下内容添加到您的 Cargo.toml 文件中

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

快速入门

use rucron::{sync_execute, 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 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)
   }
}

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

#[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
                // 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;
    });
}
*/

安排参数化作业

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;
}

您还可以安排阻塞或 CPU 密集型任务。

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> {
        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;
}

如果您想安排具有分布式锁的作业,请参阅 [示例] 目录。

许可证

Rucron 采用 MIT 许可证

贡献

欢迎贡献。除非您明确说明,否则根据 MIT 许可证定义,任何有意提交以包含在作品中的贡献,都将按照上述方式双重许可,不附加任何额外条款或条件。

依赖项

~7–20MB
~260K SLoC