3 个版本
0.1.2 | 2022年1月26日 |
---|---|
0.1.1 | 2022年1月25日 |
0.1.0 | 2022年1月25日 |
#13 in #wheel
15KB
297 行
wheel-timer2
基于多时间轮结构的定时器
此库使用多层时间轮结构。
当任务添加到轮中时,它将首先进入最粗粒度的时间轮,然后进入更高粒度的时间轮,直到达到指定时间。
如果任务太长而无法适合所有轮,则将通过添加 round
来运行任务,如果有太多太长的任务,它将导致许多任务累积在最粗粒度轮中,因此应根据实际需要调整轮的层数、容量和粒度以避免这种情况。
更准确地说,这是一个用于管理和运行定时任务的结构,而不是一个完整的定时器,因为用户自己需要定期推动(执行)它。
使用方法
- 首先,我们创建一个
MultiWheel
let mut wheel = MultiWheel::new(3, 10, Duration::from_millis(100));
这意味着创建一个3层循环,每层有10个槽位。每个槽位相差100ms
- 然后,我们添加一个在延迟300ms后打印“Hello World”的任务
let add_handle = wheel.add_handle();
add_handle
.add(
|| {
println!("hello");
},
Duration::from_millis(300),
)
.unwrap();
提示:AddHandle 是在时间轮运行时用于将任务添加到时间轮的句柄。
- 最后,我们运行时间轮
let mut i = tokio::time::interval(Duration::from_millis(100));
loop {
i.tick().await;
wheel.tick();
}
滴答间隔必须与创建时间轮时指定的粒度一致。否则,任务将在错误的时间执行。
示例
查看 示例
精度
在正常情况下,误差主要是每次运行滴答的误差加上滴答消耗的时间。
我建议使用 tokio::time::interval
而不是简单地使用 loop+sleep,因为您可以调整 MissedTickBehavior
以尝试补偿精度。
如果任务的时间小于时间轮的粒度,则它将被安排在下一个滴答或一个粒度时间后运行,具体取决于任务时间是否更接近粒度时间或0。
依赖项
~350KB