#任务调度器 #调度器 #cron #任务 #时间 #wasm #cron 表达式

tsuki-scheduler

适用于每个运行时的简单、轻量级、可组合和可扩展的调度器

4 个版本

0.1.3 2024年6月25日
0.1.2 2024年6月20日
0.1.1 2024年6月12日
0.1.0 2024年6月9日

并发类别中排名第 170

Download history 272/week @ 2024-06-07 111/week @ 2024-06-14 181/week @ 2024-06-21 18/week @ 2024-06-28 11/week @ 2024-07-05 43/week @ 2024-07-26 8/week @ 2024-08-02 3/week @ 2024-08-09

每月下载量 54

Apache-2.0 协议

43KB
1K SLoC

Tsuki-Scheduler

Crates.io Version Release status docs.rs

适用于每个运行时的简单、轻量级、可组合和可扩展的调度器。

Scheduler = Schedule × Runtime

用法

这个小型 crate 可以帮助您在以下运行时中运行任务:

  • tokio
  • async-std
  • 新线程
  • 本地
  • 承诺
  • 只要实现了在运行时创建任务的方式。

结合以下功能:

  • cron 调度
  • 一次性或定期
  • 在某个时间之前或之后
  • UTC 日期时间迭代器
  • 等等,只要实现了 trait Schedule

有关更详细的文档,请参阅 rust doc

cargo add tsuki-scheduler

tsuki-scheduler = "0.1"

创建调度器

use tsuki_scheduler::prelude::*;
let mut scheduler = Scheduler::new(Tokio);
let mut scheduler = Scheduler::new(AsyncStd);
let mut scheduler = Scheduler::new(Promise);
let mut scheduler = Scheduler::new(Thread);

// or you may use the async wrapper
let mut scheduler_runner = AsyncSchedulerRunner::<Tokio>::default();
let client = scheduler_runner.client();

组合调度

如果我想创建一个非常复杂的调度器,该怎么办

  1. 首先,它将在 10 秒后运行。
  2. 然后,它将在每个小时的第 10 分钟运行。
  3. 同时,它将每 80 分钟运行一次。
  4. 但是,它不会在最后一次运行后的 30 分钟内运行。
  5. 最后,它将在 100 天后停止运行。

实际上,您可以做到这一点

use tsuki_scheduler::prelude::*;
use chrono::TimeDelta;

let start_time = now() + TimeDelta::seconds(10);
let schedule = Once::new(start_time)
    .then(
        Cron::utc_from_cron_expr("00 10 * * * *")
            .expect("invalid cron")
            .or(Period::new(
                TimeDelta::minutes(80),
                start_time + TimeDelta::minutes(80),
            ))
            .throttling(TimeDelta::minutes(30)),
    )
    .before(start_time + TimeDelta::days(100));

对于某些情况,您想为所有调度使用某种类型,您可以使用 Box<dyn Schedule>,并且还有一个构建器 API。

use tsuki_scheduler::prelude::*;
use chrono::{Utc, TimeDelta};
let cron_list = Vec::<Cron<Utc>>::new();
// add some cron expr

// ...

// build schedule
let start_time = now() + TimeDelta::seconds(10);
let mut schedule_builder = Once::new(start_time).dyn_builder()
    .then(
        Cron::utc_from_cron_expr("00 10 * * * *")
            .expect("invalid cron")
            .or(Period::new(
                TimeDelta::minutes(80),
                start_time + TimeDelta::minutes(80),
            ))
            .throttling(TimeDelta::minutes(30)),
    )
    .before(start_time + TimeDelta::days(100));
// collect all cron expr
schedule_builder = cron_list.into_iter().fold(schedule_builder, ScheduleDynBuilder::or);
let schedule = schedule_builder.build();

添加执行和删除任务

use tsuki_scheduler::prelude::*;
let mut scheduler = Scheduler::new(Tokio);
let hello_tsuki_task = Task::tokio(
    Cron::local_from_cron_expr("*/2 * * * * *").unwrap(),
    || async {
        println!("Hello, tsuki!");
    },
);
let id = TaskUid::uuid();
scheduler.add_task(id, hello_tsuki_task);
scheduler.execute_by_now();
scheduler.delete_task(id);

管理句柄

如果您想管理句柄,可以实施自己的管理器,通过实现 trait HandleManager

异步运行时

在异步运行时中,您可以为主调度器创建一个任务,该任务由事件循环驱动的定期执行。此 crate 提供了一个实现,您可以查看 tokio 运行时的 示例

功能标志

标志 描述
uuid 允许通过 uuid-v4 创建 TaskUid
cron 允许创建由 cron 表达式描述的调度
tokio 启用 tokio 运行时
async_std 启用 async_std 运行时
thread 启用线程运行时
承诺 启用 JavaScript Promise 运行时
async-scheduler 异步运行时的默认异步包装器

替代 Crates

依赖关系

~1–14MB
~172K SLoC