#tokio #调度器 #定时器 #任务调度器 #异步 #corn

tokio-easy-timer

一个基于tokio的任务调度器,具有用户友好的API

2个版本

0.1.1 2022年8月4日
0.1.0 2022年8月3日

#807 in 异步

MIT/Apache

40KB
836 代码行

tokio-easy-timer

tokio-easy-timer是一个基于tokio的任务调度器,具有用户友好的API。

灵感来源于clokwerk

特性

  • 简单:使用作业构建器构建corn表达式和任务函数
  • 整洁:使用扩展映射管理数据
  • 异步:支持异步和同步作业
  • Cron表达式:支持使用标准cron表达式

示例

基本用法(同步,互斥锁)

use std::sync::{Arc, Mutex};

use tokio_easy_timer::prelude::*;

struct Config {
    id: i32,
}

#[tokio::main]
async fn main() {
    let mut cheduler = Scheduler::new();
    let config = Arc::new(Mutex::new(Config { id: 0 }));
    cheduler.add_ext(config);

    for _ in 0..10000 {
        cheduler.add(
            SyncJob::new()
                .every(20.seconds())
                .run(|config: Data<Arc<Mutex<Config>>>| {
                    if let Ok(mut config) = config.lock() {
                        config.id += 1;
                    }
                }),
        );
    }

    cheduler.add(SyncJob::new().since_every(10.seconds(), 20.seconds()).run(
        |config: Data<Arc<Mutex<Config>>>| {
            if let Ok(config) = config.lock() {
                println!("{}", config.id);
            }
        },
    ));

    cheduler.run_pending().await;
}

更多定时器示例

use std::sync::Arc;

use parking_lot::Mutex;
use tokio_easy_timer::prelude::*;

struct Config {
    id: i32,
}

#[tokio::main]
async fn main() {
    let mut cheduler = Scheduler::with_tz(chrono::FixedOffset::east(8 * 3600));

    // add whatever you want to the map
    let config = Arc::new(Mutex::new(Config { id: 1 }));
    cheduler.add_ext(config);
    cheduler.add_ext("a".to_string());
    cheduler.add_ext(1);

    cheduler
        .add(
            SyncJob::new()
                .every(Interval::Monday)
                .repeat_seq(3, 1.seconds())
                .run(|| {
                    // Some havey job, like complex calculate or read/write from DB.
                }),
        )
        .add(
            AsyncJob::new()
                // Runs every 90 minutes after 14:13:00 every Saturday
                .every(Interval::Saturday)
                .every(Interval::Sunday)
                .and() // use and to start build another corn expression
                // Runs every two hours on Saturdays
                .every(Interval::Sunday)
                .every(2.hour())
                .and()
                // Runs every 90 minutes after 14:13:00 every Saturday
                .every(Interval::Sunday)
                .since_time(14, 13, 0)
                .every(10.minutes())
                .repeat_async(2, 3.seconds()) // repeat
                .and()
                // Runs every 90 seconds, this needs two corn expression
                .since_every(0.minutes(), 3.minutes()) // Runs every 3 minutes starting at 0:00
                .and()
                .since_every(1.minutes(), 3.minutes()) // Runs every 3 minutes starting at 1:30
                .at(30.seconds())
                .run(|config: Data<Arc<Mutex<Config>>>| async move {
                    let mut config = config.lock();
                    config.id += 1;
                    println!("{}", config.id);
                }),
        )
        .run_pending()
        .await;
}

与teloxide(异步电报机器人库)一起工作

use dotenv::dotenv;
use std::sync::Arc;

use teloxide::{
    prelude::AutoSend,
    requests::{Request, Requester, RequesterExt},
    types::ChatId,
    Bot,
};
use tokio_easy_timer::prelude::*;

#[tokio::main]
async fn main() {
    dotenv().ok();
    let bot = Arc::new(Bot::from_env().auto_send());
    let mut scheduler = Scheduler::new();
    scheduler.add_ext(bot);

    scheduler
        .add(
            AsyncJob::new()
                .every(10.seconds())
                .run(|bot: Data<Arc<AutoSend<Bot>>>| async move {
                    bot.send_message(
                        // set your own char id here !
                        ChatId(std::env::var("CHAT_ID").unwrap().parse().unwrap()),
                        format!("Hi!"),
                    )
                    .send()
                    .await
                    .unwrap();
                }),
        )
        .run_pending()
        .await;
}

贡献

依赖

~5–12MB
~121K SLoC