Перечисление Missed Tick Behavior
pub enum MissedTickBehavior {
Burst,
Delay,
Skip,
}
time.Определяет поведение Interval при пропуске такта.
Иногда такт Interval пропускается. Например, рассмотрим следующий случай:
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().
По умолчанию, если такт пропущен, Interval выдаёт такты как можно быстрее, пока не «догонит» расписание. MissedTickBehavior позволяет задать для Interval другое поведение. Каждый вариант представляет отдельную стратегию.
Обратите внимание: поскольку исполнитель не может гарантировать точность таймеров, эти стратегии применяются только при задержке более 5 миллисекунд.
Варианты
Burst
Выдаёт такты как можно быстрее, пока не догонит расписание.
При использовании этой стратегии Interval планирует такты «обычным» образом (так же, как если бы такты не задерживались), в результате чего выдаёт их как можно быстрее, пока не догонит расписание. В отличие от Delay и Skip, такты, выдаваемые при использовании Burst (значения Instant, возвращаемые методом tick), не отличаются от тех, которые были бы возвращены, если бы такт не был пропущен. Как и при использовании Skip, и в отличие от Delay, интервалы между тактами могут сокращаться.
Это выглядит примерно так:
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 или interval_at.
Delay
Выдаёт такты с интервалом period, отсчитываемым от момента вызова tick, а не от start.
При использовании этой стратегии, если Interval пропустил такт, вместо планирования тактов с интервалом period от start (момента выдачи первого такта) все будущие такты планируются через равные промежутки period, отсчитываемые от момента вызова tick. В отличие от Burst и Skip, интервалы между тактами не сокращаются, и больше не гарантируется, что такты будут происходить с интервалом, кратным period, от start.
Это выглядит примерно так:
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
Пропускает пропущенные такты и выдаёт следующий такт в ближайший момент, кратный period от start.
При использовании этой стратегии Interval планирует следующий такт на ближайший следующий момент, отстоящий на величину, кратную period от start (момента выдачи первого такта Interval). Как и при использовании Burst, все такты остаются кратными period относительно start, но, в отличие от Burst, интервал между тактами может быть не равен одному интервалу, кратному period. Как и при использовании Delay, такты уже не совпадают с теми, которые были бы выданы, если бы такты не пропускались, но, в отличие от Delay и как при использовании Burst, интервалы между тактами могут сокращаться и быть меньше одного 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;Реализации трейтов
impl Clone for MissedTickBehavior
fn clone(&self) -> MissedTickBehavior
fn clone_from(&mut self, source: &Self)
source. Подробнее
impl Copy for MissedTickBehavior
impl Debug for MissedTickBehavior
impl Default for MissedTickBehavior
fn default() -> Self
Возвращает MissedTickBehavior::Burst.
В большинстве случаев предпочтительна стратегия Burst. Кроме того, для сохранения обратной совместимости стратегией по умолчанию должна быть Burst. По этим причинам MissedTickBehavior::Burst является значением по умолчанию для MissedTickBehavior. Подробнее см. Burst.
impl Eq for MissedTickBehavior
impl PartialEq for MissedTickBehavior
impl StructuralPartialEq for MissedTickBehavior
Автоматические реализации трейтов
impl Freeze for MissedTickBehavior
impl RefUnwindSafe for MissedTickBehavior
impl Send for MissedTickBehavior
impl Sync for MissedTickBehavior
impl Unpin for MissedTickBehavior
impl UnsafeUnpin for MissedTickBehavior
impl UnwindSafe for MissedTickBehavior
Обобщённые реализации
impl<T> BorrowMut<T> for Twhere T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
impl<T> CloneToUninit for Twhere T: Clone,
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)
impl<T> Instrument for T
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
impl<T> ToOwned for Twhere T: Clone,
type Owned = T
fn to_owned(&self) -> T
fn clone_into(&self, target: &mut T)
impl<T> WithSubscriber for T
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Subscriber к этому типу и возвращает обёртку WithDispatch. Подробнее
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/time/enum.MissedTickBehavior.html