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次 下载
81KB
1.5K SLoC
Rucron:一个纯 Rust 实现的作业调度包。
Rucron 是一个轻量级的作业调度器,类似于 gocron 或 Linux crontab,并且非常易于使用。现在 rucron 兼容 smol
和 tokio
。
用法
将以下内容添加到您的 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