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 指定不同的行为。每个变体代表一种不同的策略。
请注意,由于 executor 无法保证定时器的精确性,这些策略仅在延迟大于 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 实现§
Source§impl Clone for MissedTickBehavior
impl Clone for MissedTickBehavior
Source§fn clone(&self) -> MissedTickBehavior
fn clone(&self) -> MissedTickBehavior
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. 更多信息Source§impl Debug for MissedTickBehavior
impl Debug for MissedTickBehavior
Source§impl Default for MissedTickBehavior
impl Default for MissedTickBehavior
Source§fn default() -> Self
fn default() -> Self
对于大多数用例,Burst 策略是所需的选择。此外,为了保持向后兼容性,Burst 策略必须是默认策略。基于这些原因,MissedTickBehavior::Burst 是 MissedTickBehavior 的默认值。有关更多详细信息,请参阅 Burst。