#scheduler #tokio #timer #task-scheduler #async #corn

tokio-easy-timer

A tokio-based task scheduler, with a user-friendly API

2 releases

0.1.1 Aug 4, 2022
0.1.0 Aug 3, 2022

#720 in Asynchronous

31 downloads per month

MIT/Apache

40KB
836 lines

tokio-easy-timer

tokio-easy-timer is a tokio-based task scheduler, with a user-friendly API.

Inspired by clokwerk

Features

  • Easy: use job builder to build corn expression and task func
  • Clean: use extension map to manage data
  • Async: support both async and sync job
  • Cron Expressions: support for using standard corn expressions

Examples

Basic Usage (sync, mutex)

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

More Timer Example

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

Work with teloxide (async telegram bot library)

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

Contributing

Dependencies

~5–13MB
~118K SLoC