#wheel #time #structure #task #timer #multi-time #granularity

wheel-timer2

基于多时间轮结构的定时器

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

基于多时间轮结构的定时器

docs.rs

此库使用多层时间轮结构。

当任务添加到轮中时,它将首先进入最粗粒度的时间轮,然后进入更高粒度的时间轮,直到达到指定时间。

如果任务太长而无法适合所有轮,则将通过添加 round 来运行任务,如果有太多太长的任务,它将导致许多任务累积在最粗粒度轮中,因此应根据实际需要调整轮的层数、容量和粒度以避免这种情况。

更准确地说,这是一个用于管理和运行定时任务的结构,而不是一个完整的定时器,因为用户自己需要定期推动(执行)它。

使用方法

  1. 首先,我们创建一个 MultiWheel
let mut wheel = MultiWheel::new(3, 10, Duration::from_millis(100));

这意味着创建一个3层循环,每层有10个槽位。每个槽位相差100ms

  1. 然后,我们添加一个在延迟300ms后打印“Hello World”的任务
let add_handle = wheel.add_handle();

add_handle
    .add(
        || {
            println!("hello");
        },
        Duration::from_millis(300),
    )
    .unwrap();

提示:AddHandle 是在时间轮运行时用于将任务添加到时间轮的句柄。

  1. 最后,我们运行时间轮
let mut i = tokio::time::interval(Duration::from_millis(100));
loop {
    i.tick().await;
    wheel.tick();
}

滴答间隔必须与创建时间轮时指定的粒度一致。否则,任务将在错误的时间执行。

示例

查看 示例

精度

在正常情况下,误差主要是每次运行滴答的误差加上滴答消耗的时间。

我建议使用 tokio::time::interval 而不是简单地使用 loop+sleep,因为您可以调整 MissedTickBehavior 以尝试补偿精度。

如果任务的时间小于时间轮的粒度,则它将被安排在下一个滴答或一个粒度时间后运行,具体取决于任务时间是否更接近粒度时间或0。

依赖项

~350KB