pub enum MissedTickBehavior {
Burst,
Delay,
Skip,
}展开描述
定义 Interval 错过 tick 时的行为。
有时,Interval 的 tick 会被错过。例如,请考虑以下情况:
use tokio::time::{self, Duration};
// ticks every 2 milliseconds
let mut interval = time::interval(Duration::from_millis(2));
for _ in 0..5 {
interval.tick().await;
// if this takes more than 2 milliseconds, a tick will be delayed
task_that_takes_one_to_three_millis().await;
}一般来说,如果在调用 Interval::tick() 之前花费了太多时间,则会错过 tick。
默认情况下,当错过 tick 时,Interval 会尽快触发 tick,直到它在时间上"赶上"它应该在的位置。可以使用 MissedTickBehavior 来为 Interval 指定不同的行为。每个变体代表一种不同的策略。
请注意,由于执行器无法保证计时器的精确精度,因此这些策略仅在延迟大于 5 毫秒时适用。
变体§
Burst
尽可能快地触发 tick,直到赶上为止。
当使用此策略时,Interval 以"正常"方式调度 tick(与 tick 没有延迟时的方式相同),这会导致它尽快触发 tick,直到它在时间上赶上它应该在的位置。与 Delay 和 Skip 不同,使用 Burst 时产生的 tick(tick 产生的 Instant)与未错过 tick 时没什么不同。与 Skip 类似,与 Delay 不同,tick 可能会被缩短。
大致如下:
Expected ticks: | 1 | 2 | 3 | 4 | 5 | 6 |
Actual ticks: | work -----| delay | work | work | work -| work -----|代码:
use tokio::time::{interval, Duration};
let mut interval = interval(Duration::from_millis(50));
// First tick resolves immediately after creation
interval.tick().await;
task_that_takes_200_millis().await;
// The `Interval` has missed a tick
// Since we have exceeded our timeout, this will resolve immediately
interval.tick().await;
// Since we are more than 100ms after the start of `interval`, this will
// also resolve immediately.
interval.tick().await;
// Also resolves immediately, because it was supposed to resolve at
// 150ms after the start of `interval`
interval.tick().await;
// Resolves immediately
interval.tick().await;
// Since we have gotten to 200ms after the start of `interval`, this
// will resolve after 50ms
interval.tick().await;这是使用 interval 和 interval_at 创建 Interval 时的默认行为。
Delay
从调用 tick 开始以 period 的倍数触发 tick,而不是从 start 开始。
当使用此策略并且 Interval 错过一个 tick 时,它不会从 start(第一个 tick 触发的时间)开始以 period 的倍数调度 tick 触发,而是将所有未来的 tick 调度为从调用 tick 的点开始以规则 period 发生。与 Burst 和 Skip 不同,tick 不会被缩短,也不再保证以从 start 开始的 period 的倍数发生。
大致如下:
Expected ticks: | 1 | 2 | 3 | 4 | 5 | 6 |
Actual ticks: | work -----| delay | work -----| work -----| work -----|代码:
use tokio::time::{interval, Duration, MissedTickBehavior};
let mut interval = interval(Duration::from_millis(50));
interval.set_missed_tick_behavior(MissedTickBehavior::Delay);
task_that_takes_more_than_50_millis().await;
// The `Interval` has missed a tick
// Since we have exceeded our timeout, this will resolve immediately
interval.tick().await;
// But this one, rather than also resolving immediately, as might happen
// with the `Burst` or `Skip` behaviors, will not resolve until
// 50ms after the call to `tick` up above. That is, in `tick`, when we
// recognize that we missed a tick, we schedule the next tick to happen
// 50ms (or whatever the `period` is) from right then, not from when
// were *supposed* to tick
interval.tick().await;Skip
跳过错过的 tick,并在从 start 开始的下一个 period 倍数上 tick。
当使用此策略时,Interval 将下一个 tick 调度为在距离 start(Interval 第一次 tick 的点)的 period 下一个最近倍数处触发。与 Burst 类似,所有 tick 都保持距 start 的 period 的倍数,但与 Burst 不同,tick 可能距上一个 tick 不是 period 的一个倍数。与 Delay 类似,tick 不再与未错过 tick 时相同,但与 Delay 不同且与 Burst 类似,tick 可能会被缩短到彼此相隔不到一个 period。
大致如下:
Expected ticks: | 1 | 2 | 3 | 4 | 5 | 6 |
Actual ticks: | work -----| delay | work ---| work -----| work -----|代码:
use tokio::time::{interval, Duration, MissedTickBehavior};
let mut interval = interval(Duration::from_millis(50));
interval.set_missed_tick_behavior(MissedTickBehavior::Skip);
task_that_takes_75_millis().await;
// The `Interval` has missed a tick
// Since we have exceeded our timeout, this will resolve immediately
interval.tick().await;
// This one will resolve after 25ms, 100ms after the start of
// `interval`, which is the closest multiple of `period` from the start
// of `interval` after the call to `tick` up above.
interval.tick().await;trait 实现§
源代码§impl Clone for MissedTickBehavior
impl Clone for MissedTickBehavior
源代码§fn clone(&self) -> MissedTickBehavior
fn clone(&self) -> MissedTickBehavior
1.0.0 · 源代码§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. 更多信息源代码§impl Debug for MissedTickBehavior
impl Debug for MissedTickBehavior
源代码§impl 默认值 for MissedTickBehavior
impl 默认值 for MissedTickBehavior
源代码§fn default() -> Self
fn default() -> Self
对于大多数用例,Burst 策略正是所需要的。此外,为了保持向后兼容性,Burst 策略必须是默认策略。出于这些原因,MissedTickBehavior::Burst 是 MissedTickBehavior 的默认值。有关更多详细信息,请参阅 Burst。