Rust定时任务管理库delay_timer的使用,轻量级高性能的延迟任务调度与执行工具
Rust定时任务管理库delay_timer的使用,轻量级高性能的延迟任务调度与执行工具
delay-timer是一个基于时间轮算法的任务管理器,可以轻松管理定时任务或定期执行任意任务(如闭包)。底层运行时基于可选的smol和tokio,您可以选择其中任何一个来构建您的应用程序。
主要特性
- 支持配置任务的最大并行数
- 通过句柄动态取消正在运行的任务实例
- 支持同步和异步任务
- 可以指定具体日期执行任务(如每周日凌晨4点执行备份任务)
- 最小支持的rustc版本是1.56
示例代码
基础使用示例
use anyhow::Result;
use delay_timer::prelude::*;
fn main() -> Result<()> {
// 构建一个使用Smol运行时默认配置的DelayTimer
let delay_timer = DelayTimerBuilder::default().build();
// 开发一个异步循环运行的打印任务
let task_instance_chain = delay_timer.insert_task(build_task_async_print()?)?;
// 获取任务1的运行实例
let task_instance = task_instance_chain.next_with_wait()?;
// 取消正在运行的任务实例
task_instance.cancel_with_wait()?;
// 移除ID为1的任务
delay_timer.remove_task(1)?;
// 不再接受新任务;运行中的任务不受影响
delay_timer.stop_delay_timer()?;
Ok(())
}
fn build_task_async_print() -> Result<Task, TaskError> {
let mut task_builder = TaskBuilder::default();
let body = || async {
println!("create_async_fn_body!");
Timer::after(Duration::from_secs(3).await;
println!("create_async_fn_body:i'success");
};
task_builder
.set_task_id(1)
.set_frequency_repeated_by_cron_str("@secondly")
.set_maximum_parallel_runnable_num(2)
.spawn_async_routine(body)
}
异步上下文中使用
use delay_timer::prelude::*;
use anyhow::Result;
use smol::Timer;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
// 构建一个使用Smol运行时默认配置的DelayTimer
let delay_timer = DelayTimerBuilder::default().build();
// 开发一个异步循环运行的打印任务
let task_instance_chain = delay_timer.insert_task(build_task_async_print()?)?;
// 获取任务1的运行实例
let task_instance = task_instance_chain.next_with_async_wait().await?;
// 取消正在运行的任务实例
task_instance.cancel_with_async_wait().await?;
// 移除ID为1的任务
delay_timer.remove_task(1)?;
// 不再接受新任务;运行中的任务不受影响
delay_timer.stop_delay_timer()
}
fn build_task_async_print() -> Result<Tail, TaskError> {
let mut task_builder = TaskBuilder::default();
let body = || async {
println!("create_async_fn_body!");
Timer::after(Duration::from_secs(3)).await;
println!("create_async_fn_body:i'success");
};
task_builder
.set_task_id(1)
.set_frequency_repeated_by_cron_str("@secondly")
.set_maximum_parallel_runnable_num(2)
.spawn_async_routine(body)
}
捕获指定环境信息并构建闭包和任务
#[macro_use]
use delay_timer::prelude::*;
use std::sync::atomic::{
AtomicUsize,
Ordering::{Acquire, Release},
};
use std::sync::Arc;
let delay_timer = DelayTimer::new();
let share_num = Arc::new(AtomicUsize::new(0));
let share_num_bunshin = share_num.clone();
let body = move || {
share_num_bunshin.fetch_add(1, Release);
};
let task = TaskBuilder::default()
.set_frequency_count_down_by_cron_str(expression, 3)
.set_task_id(1)
.spawn_routine(body)?;
delay_timer.add_task(task)?;
构建自定义动态未来任务
#[macro_use]
use delay_timer::prelude::*;
use hyper::{Client, Uri};
fn build_task_customized_async_task() -> Result<Task, TaskError> {
let id = 1;
let name = String::from("someting");
let mut task_builder = TaskBuilder::default();
let body = move || {
let name_ref = name.clone();
async move {
async_template(id, name_ref).await.expect("Request failed.");
sleep(Duration::from_secs(3)).await;
println!("create_async_fn_body:i'success");
}
};
task_builder
.set_frequency_repeated_by_cron_str("0,10,15,25,50 0/1 * * Jan-Dec * 2020-2100")
.set_task_id(5)
.set_maximum_running_time(5)
.spawn_async_routine(body)
}
pub async fn async_template(id: i32, name: String) -> Result<()> {
let url = format!("https://httpbin.org/get?id={}&name={}", id, name);
let mut res = surf::get(url).await?;
dbg!(res.body_string().await?);
Ok(())
}
完整示例Demo
以下是一个完整的定时任务示例,展示了如何创建一个周期性执行的HTTP请求任务:
use delay_timer::prelude::*;
use anyhow::Result;
use surf; // HTTP客户端
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
// 创建延迟定时器
let delay_timer = DelayTimerBuilder::default().build();
// 创建HTTP请求任务
let task = build_http_task()?;
// 添加任务到定时器
delay_timer.insert_task(task)?;
// 让主线程等待一段时间,观察任务执行
tokio::time::sleep(Duration::from_secs(30)).await;
Ok(())
}
fn build_http_task() -> Result<Task, TaskError> {
let mut task_builder = TaskBuilder::default();
// 定义任务体 - 每5秒发送一次HTTP请求
let body = || async {
println!("准备发送HTTP请求...");
match surf::get("https://httpbin.org/get").await {
Ok(mut res) => {
println!("响应状态: {}", res.status());
if let Ok(body) = res.body_string().await {
println!("响应内容: {}", body);
}
}
Err(e) => eprintln!("请求失败: {}", e),
}
};
task_builder
.set_task_id(1)
.set_frequency_repeated_by_cron_str("*/5 * * * * *") // 每5秒执行一次
.set_maximum_parallel_runnable_num(1)
.spawn_async_routine(body)
}
许可证
delay-timer采用MIT或Apache-2.0双许可证授权。
1 回复
Rust定时任务管理库delay_timer使用指南
简介
delay_timer
是一个轻量级高性能的Rust延迟任务调度与执行工具库,专为需要定时任务管理的应用场景设计。它提供了简单易用的API来安排延迟执行或周期性执行的任务。
主要特性
- 轻量级设计,低资源占用
- 高性能任务调度
- 支持一次性延迟任务和周期性任务
- 线程安全的任务管理
- 简单的API接口
基本使用方法
添加依赖
首先在Cargo.toml
中添加依赖:
[dependencies]
delay_timer = "0.11"
创建定时器实例
use delay_timer::prelude::*;
fn main() {
// 创建定时器实例
let timer = DelayTimerBuilder::default().build();
// 或者使用自定义配置
let timer = DelayTimerBuilder::default()
.tokio_runtime_by_default()
.build()
.unwrap();
}
添加一次性任务
async fn one_shot_task() {
println!("This task runs once after delay");
}
fn main() {
let timer = DelayTimerBuilder::default().build().unwrap();
let task = TaskBuilder::default()
.set_task_id(1)
.set_frequency(Frequency::Once)
.set_maximun_parallel_runable_num(1)
.spawn(one_shot_task())
.unwrap();
timer.add_task(task).unwrap();
}
添加周期性任务
async fn periodic_task() {
println!("This task runs periodically");
}
fn main() {
let timer = DelayTimerBuilder::default().build().unwrap();
let task = TaskBuilder::default()
.set_task_id(2)
.set_frequency(Frequency::Repeated("*/5 * * * * *"))
.set_maximun_parallel_runable_num(1)
.spawn(periodic_task())
.unwrap();
timer.add_task(task).unwrap();
}
高级用法
带参数的任务
async fn task_with_args(arg: i32) {
println!("Task received argument: {}", arg);
}
fn main() {
let timer = DelayTimerBuilder::default().build().unwrap();
let task = TaskBuilder::default()
.set_task_id(3)
.set_frequency(Frequency::Once)
.set_maximun_parallel_runable_num(1)
.spawn(async {
task_with_args(42).await;
})
.unwrap();
timer.add_task(task).unwrap();
}
动态取消任务
fn main() {
let timer = DelayTimerBuilder::default().build().unwrap();
// 添加任务并获取任务句柄
let task = TaskBuilder::default()
.set_task_id(4)
.set_frequency(Frequency::Repeated("*/10 * * * * *"))
.set_maximun_parallel_runable_num(1)
.spawn(async {
println!("This task will be cancelled");
})
.unwrap();
let task_id = task.get_task_id();
timer.add_task(task).unwrap();
// 稍后取消任务
std::thread::sleep(std::time::Duration::from_secs(30));
timer.remove_task(task_id).unwrap();
}
完整示例
下面是一个完整的示例,演示如何使用delay_timer创建和管理定时任务:
use delay_timer::prelude::*;
use std::time::Duration;
// 一次性任务
async fn one_time_job() {
println!("一次性任务执行了!");
}
// 周期性任务
async fn periodic_job() {
println!("周期性任务执行了!");
}
// 带参数的任务
async fn job_with_params(name: &str, count: i32) {
println!("任务'{}'执行了{}次", name, count);
}
#[tokio::main]
async fn main() {
// 创建定时器实例
let timer = DelayTimerBuilder::default()
.tokio_runtime_by_default()
.build()
.unwrap();
// 添加一次性任务(10秒后执行)
let one_time_task = TaskBuilder::default()
.set_task_id(1)
.set_frequency(Frequency::Once)
.set_maximum_parallel_runnable_num(1)
.spawn(one_time_job())
.unwrap();
timer.add_task(one_time_task).unwrap();
// 添加周期性任务(每5秒执行一次)
let periodic_task = TaskBuilder::default()
.set_task_id(2)
.set_frequency(Frequency::Repeated("*/5 * * * * *"))
.set_maximum_parallel_runnable_num(1)
.spawn(periodic_job())
.unwrap();
timer.add_task(periodic_task).unwrap();
// 添加带参数的任务
let param_task = TaskBuilder::default()
.set_task_id(3)
.set_frequency(Frequency::Repeated("*/8 * * * * *"))
.set_maximum_parallel_runnable_num(1)
.spawn(async {
job_with_params("测试任务", 3).await;
})
.unwrap();
timer.add_task(param_task).unwrap();
// 让程序运行一段时间
tokio::time::sleep(Duration::from_secs(30)).await;
// 清理所有任务
timer.remove_all_tasks().unwrap();
}
注意事项
- 确保任务函数是
Send + 'static
的 - 对于长时间运行的任务,考虑使用
tokio::spawn
在任务内部 - 合理设置
maximun_parallel_runable_num
以避免资源耗尽
delay_timer
是构建需要定时任务功能的Rust应用的强大工具,它的简单API和高效实现使其成为许多场景下的理想选择。