Coverage Report

Created: 2026-08-13 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.53.1/src/time/interval.rs
Line
Count
Source
1
use crate::time::{sleep_until, Duration, Instant, Sleep};
2
use crate::util::trace;
3
4
use std::future::{poll_fn, Future};
5
use std::panic::Location;
6
use std::pin::Pin;
7
use std::task::{ready, Context, Poll};
8
9
/// Creates new [`Interval`] that yields with interval of `period`. The first
10
/// tick completes immediately. The default [`MissedTickBehavior`] is
11
/// [`Burst`](MissedTickBehavior::Burst), but this can be configured
12
/// by calling [`set_missed_tick_behavior`](Interval::set_missed_tick_behavior).
13
///
14
/// An interval will tick indefinitely. At any time, the [`Interval`] value can
15
/// be dropped. This cancels the interval.
16
///
17
/// This function is equivalent to
18
/// [`interval_at(Instant::now(), period)`](interval_at).
19
///
20
/// # Panics
21
///
22
/// This function panics if `period` is zero.
23
///
24
/// # Examples
25
///
26
/// ```
27
/// use tokio::time::{self, Duration};
28
///
29
/// # #[tokio::main(flavor = "current_thread")]
30
/// # async fn main() {
31
/// let mut interval = time::interval(Duration::from_millis(10));
32
///
33
/// interval.tick().await; // ticks immediately
34
/// interval.tick().await; // ticks after 10ms
35
/// interval.tick().await; // ticks after 10ms
36
///
37
/// // approximately 20ms have elapsed.
38
/// # }
39
/// ```
40
///
41
/// A simple example using `interval` to execute a task every two seconds.
42
///
43
/// The difference between `interval` and [`sleep`] is that an [`Interval`]
44
/// measures the time since the last tick, which means that [`.tick().await`]
45
/// may wait for a shorter time than the duration specified for the interval
46
/// if some time has passed between calls to [`.tick().await`].
47
///
48
/// If the tick in the example below was replaced with [`sleep`], the task
49
/// would only be executed once every three seconds, and not every two
50
/// seconds.
51
///
52
/// ```
53
/// use tokio::time;
54
///
55
/// async fn task_that_takes_a_second() {
56
///     println!("hello");
57
///     time::sleep(time::Duration::from_secs(1)).await
58
/// }
59
///
60
/// # #[tokio::main(flavor = "current_thread")]
61
/// # async fn main() {
62
/// let mut interval = time::interval(time::Duration::from_secs(2));
63
/// for _i in 0..5 {
64
///     interval.tick().await;
65
///     task_that_takes_a_second().await;
66
/// }
67
/// # }
68
/// ```
69
///
70
/// [`sleep`]: crate::time::sleep()
71
/// [`.tick().await`]: Interval::tick
72
#[track_caller]
73
0
pub fn interval(period: Duration) -> Interval {
74
0
    assert!(period > Duration::new(0, 0), "`period` must be non-zero.");
75
0
    internal_interval_at(Instant::now(), period, trace::caller_location())
76
0
}
77
78
/// Creates new [`Interval`] that yields with interval of `period` with the
79
/// first tick completing at `start`. The default [`MissedTickBehavior`] is
80
/// [`Burst`](MissedTickBehavior::Burst), but this can be configured
81
/// by calling [`set_missed_tick_behavior`](Interval::set_missed_tick_behavior).
82
///
83
/// An interval will tick indefinitely. At any time, the [`Interval`] value can
84
/// be dropped. This cancels the interval.
85
///
86
/// # Panics
87
///
88
/// This function panics if `period` is zero.
89
///
90
/// # Examples
91
///
92
/// ```
93
/// use tokio::time::{interval_at, Duration, Instant};
94
///
95
/// # #[tokio::main(flavor = "current_thread")]
96
/// # async fn main() {
97
/// let start = Instant::now() + Duration::from_millis(50);
98
/// let mut interval = interval_at(start, Duration::from_millis(10));
99
///
100
/// interval.tick().await; // ticks after 50ms
101
/// interval.tick().await; // ticks after 10ms
102
/// interval.tick().await; // ticks after 10ms
103
///
104
/// // approximately 70ms have elapsed.
105
/// # }
106
/// ```
107
#[track_caller]
108
0
pub fn interval_at(start: Instant, period: Duration) -> Interval {
109
0
    assert!(period > Duration::new(0, 0), "`period` must be non-zero.");
110
0
    internal_interval_at(start, period, trace::caller_location())
111
0
}
112
113
#[cfg_attr(not(all(tokio_unstable, feature = "tracing")), allow(unused_variables))]
114
0
fn internal_interval_at(
115
0
    start: Instant,
116
0
    period: Duration,
117
0
    location: Option<&'static Location<'static>>,
118
0
) -> Interval {
119
    #[cfg(all(tokio_unstable, feature = "tracing"))]
120
    let resource_span = {
121
        let location = location.expect("should have location if tracing");
122
123
        tracing::trace_span!(
124
            parent: None,
125
            "runtime.resource",
126
            concrete_type = "Interval",
127
            kind = "timer",
128
            loc.file = location.file(),
129
            loc.line = location.line(),
130
            loc.col = location.column(),
131
        )
132
    };
133
134
0
    Interval {
135
0
        delay: Box::pin(sleep_until(start)),
136
0
        period,
137
0
        missed_tick_behavior: MissedTickBehavior::default(),
138
0
        #[cfg(all(tokio_unstable, feature = "tracing"))]
139
0
        resource_span,
140
0
    }
141
0
}
142
143
/// Defines the behavior of an [`Interval`] when it misses a tick.
144
///
145
/// Sometimes, an [`Interval`]'s tick is missed. For example, consider the
146
/// following:
147
///
148
/// ```
149
/// use tokio::time::{self, Duration};
150
/// # async fn task_that_takes_one_to_three_millis() {}
151
///
152
/// # #[tokio::main(flavor = "current_thread")]
153
/// # async fn main() {
154
/// // ticks every 2 milliseconds
155
/// let mut interval = time::interval(Duration::from_millis(2));
156
/// for _ in 0..5 {
157
///     interval.tick().await;
158
///     // if this takes more than 2 milliseconds, a tick will be delayed
159
///     task_that_takes_one_to_three_millis().await;
160
/// }
161
/// # }
162
/// ```
163
///
164
/// Generally, a tick is missed if too much time is spent without calling
165
/// [`Interval::tick()`].
166
///
167
/// By default, when a tick is missed, [`Interval`] fires ticks as quickly as it
168
/// can until it is "caught up" in time to where it should be.
169
/// `MissedTickBehavior` can be used to specify a different behavior for
170
/// [`Interval`] to exhibit. Each variant represents a different strategy.
171
///
172
/// Note that because the executor cannot guarantee exact precision with timers,
173
/// these strategies will only apply when the delay is greater than 5
174
/// milliseconds.
175
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
176
pub enum MissedTickBehavior {
177
    /// Ticks as fast as possible until caught up.
178
    ///
179
    /// When this strategy is used, [`Interval`] schedules ticks "normally" (the
180
    /// same as it would have if the ticks hadn't been delayed), which results
181
    /// in it firing ticks as fast as possible until it is caught up in time to
182
    /// where it should be. Unlike [`Delay`] and [`Skip`], the ticks yielded
183
    /// when `Burst` is used (the [`Instant`]s that [`tick`](Interval::tick)
184
    /// yields) aren't different than they would have been if a tick had not
185
    /// been missed. Like [`Skip`], and unlike [`Delay`], the ticks may be
186
    /// shortened.
187
    ///
188
    /// This looks something like this:
189
    /// ```text
190
    /// Expected ticks: |     1     |     2     |     3     |     4     |     5     |     6     |
191
    /// Actual ticks:   | work -----|          delay          | work | work | work -| work -----|
192
    /// ```
193
    ///
194
    /// In code:
195
    ///
196
    /// ```
197
    /// use tokio::time::{interval, Duration};
198
    /// # async fn task_that_takes_200_millis() {}
199
    ///
200
    /// # #[tokio::main(flavor = "current_thread")]
201
    /// # async fn main() {
202
    /// let mut interval = interval(Duration::from_millis(50));
203
    ///
204
    /// // First tick resolves immediately after creation
205
    /// interval.tick().await;
206
    ///
207
    /// task_that_takes_200_millis().await;
208
    /// // The `Interval` has missed a tick
209
    ///
210
    /// // Since we have exceeded our timeout, this will resolve immediately
211
    /// interval.tick().await;
212
    ///
213
    /// // Since we are more than 100ms after the start of `interval`, this will
214
    /// // also resolve immediately.
215
    /// interval.tick().await;
216
    ///
217
    /// // Also resolves immediately, because it was supposed to resolve at
218
    /// // 150ms after the start of `interval`
219
    /// interval.tick().await;
220
    ///
221
    /// // Resolves immediately
222
    /// interval.tick().await;
223
    ///
224
    /// // Since we have gotten to 200ms after the start of `interval`, this
225
    /// // will resolve after 50ms
226
    /// interval.tick().await;
227
    /// # }
228
    /// ```
229
    ///
230
    /// This is the default behavior when [`Interval`] is created with
231
    /// [`interval`] and [`interval_at`].
232
    ///
233
    /// [`Delay`]: MissedTickBehavior::Delay
234
    /// [`Skip`]: MissedTickBehavior::Skip
235
    Burst,
236
237
    /// Tick at multiples of `period` from when [`tick`] was called, rather than
238
    /// from `start`.
239
    ///
240
    /// When this strategy is used and [`Interval`] has missed a tick, instead
241
    /// of scheduling ticks to fire at multiples of `period` from `start` (the
242
    /// time when the first tick was fired), it schedules all future ticks to
243
    /// happen at a regular `period` from the point when [`tick`] was called.
244
    /// Unlike [`Burst`] and [`Skip`], ticks are not shortened, and they aren't
245
    /// guaranteed to happen at a multiple of `period` from `start` any longer.
246
    ///
247
    /// This looks something like this:
248
    /// ```text
249
    /// Expected ticks: |     1     |     2     |     3     |     4     |     5     |     6     |
250
    /// Actual ticks:   | work -----|          delay          | work -----| work -----| work -----|
251
    /// ```
252
    ///
253
    /// In code:
254
    ///
255
    /// ```
256
    /// use tokio::time::{interval, Duration, MissedTickBehavior};
257
    /// # async fn task_that_takes_more_than_50_millis() {}
258
    ///
259
    /// # #[tokio::main(flavor = "current_thread")]
260
    /// # async fn main() {
261
    /// let mut interval = interval(Duration::from_millis(50));
262
    /// interval.set_missed_tick_behavior(MissedTickBehavior::Delay);
263
    ///
264
    /// task_that_takes_more_than_50_millis().await;
265
    /// // The `Interval` has missed a tick
266
    ///
267
    /// // Since we have exceeded our timeout, this will resolve immediately
268
    /// interval.tick().await;
269
    ///
270
    /// // But this one, rather than also resolving immediately, as might happen
271
    /// // with the `Burst` or `Skip` behaviors, will not resolve until
272
    /// // 50ms after the call to `tick` up above. That is, in `tick`, when we
273
    /// // recognize that we missed a tick, we schedule the next tick to happen
274
    /// // 50ms (or whatever the `period` is) from right then, not from when
275
    /// // were *supposed* to tick
276
    /// interval.tick().await;
277
    /// # }
278
    /// ```
279
    ///
280
    /// [`Burst`]: MissedTickBehavior::Burst
281
    /// [`Skip`]: MissedTickBehavior::Skip
282
    /// [`tick`]: Interval::tick
283
    Delay,
284
285
    /// Skips missed ticks and tick on the next multiple of `period` from
286
    /// `start`.
287
    ///
288
    /// When this strategy is used, [`Interval`] schedules the next tick to fire
289
    /// at the next-closest tick that is a multiple of `period` away from
290
    /// `start` (the point where [`Interval`] first ticked). Like [`Burst`], all
291
    /// ticks remain multiples of `period` away from `start`, but unlike
292
    /// [`Burst`], the ticks may not be *one* multiple of `period` away from the
293
    /// last tick. Like [`Delay`], the ticks are no longer the same as they
294
    /// would have been if ticks had not been missed, but unlike [`Delay`], and
295
    /// like [`Burst`], the ticks may be shortened to be less than one `period`
296
    /// away from each other.
297
    ///
298
    /// This looks something like this:
299
    /// ```text
300
    /// Expected ticks: |     1     |     2     |     3     |     4     |     5     |     6     |
301
    /// Actual ticks:   | work -----|          delay          | work ---| work -----| work -----|
302
    /// ```
303
    ///
304
    /// In code:
305
    ///
306
    /// ```
307
    /// use tokio::time::{interval, Duration, MissedTickBehavior};
308
    /// # async fn task_that_takes_75_millis() {}
309
    ///
310
    /// # #[tokio::main(flavor = "current_thread")]
311
    /// # async fn main() {
312
    /// let mut interval = interval(Duration::from_millis(50));
313
    /// interval.set_missed_tick_behavior(MissedTickBehavior::Skip);
314
    ///
315
    /// task_that_takes_75_millis().await;
316
    /// // The `Interval` has missed a tick
317
    ///
318
    /// // Since we have exceeded our timeout, this will resolve immediately
319
    /// interval.tick().await;
320
    ///
321
    /// // This one will resolve after 25ms, 100ms after the start of
322
    /// // `interval`, which is the closest multiple of `period` from the start
323
    /// // of `interval` after the call to `tick` up above.
324
    /// interval.tick().await;
325
    /// # }
326
    /// ```
327
    ///
328
    /// [`Burst`]: MissedTickBehavior::Burst
329
    /// [`Delay`]: MissedTickBehavior::Delay
330
    Skip,
331
}
332
333
impl MissedTickBehavior {
334
    /// If a tick is missed, this method is called to determine when the next tick should happen.
335
0
    fn next_timeout(&self, timeout: Instant, now: Instant, period: Duration) -> Instant {
336
0
        match self {
337
0
            Self::Burst => timeout + period,
338
0
            Self::Delay => now + period,
339
            Self::Skip => {
340
0
                now + period
341
0
                    - Duration::from_nanos(
342
0
                        ((now - timeout).as_nanos() % period.as_nanos())
343
0
                            .try_into()
344
0
                            // This operation is practically guaranteed not to
345
0
                            // fail, as in order for it to fail, `period` would
346
0
                            // have to be longer than `now - timeout`, and both
347
0
                            // would have to be longer than 584 years.
348
0
                            //
349
0
                            // If it did fail, there's not a good way to pass
350
0
                            // the error along to the user, so we just panic.
351
0
                            .expect(
352
0
                                "too much time has elapsed since the interval was supposed to tick",
353
0
                            ),
354
0
                    )
355
            }
356
        }
357
0
    }
358
}
359
360
impl Default for MissedTickBehavior {
361
    /// Returns [`MissedTickBehavior::Burst`].
362
    ///
363
    /// For most usecases, the [`Burst`] strategy is what is desired.
364
    /// Additionally, to preserve backwards compatibility, the [`Burst`]
365
    /// strategy must be the default. For these reasons,
366
    /// [`MissedTickBehavior::Burst`] is the default for [`MissedTickBehavior`].
367
    /// See [`Burst`] for more details.
368
    ///
369
    /// [`Burst`]: MissedTickBehavior::Burst
370
0
    fn default() -> Self {
371
0
        Self::Burst
372
0
    }
373
}
374
375
/// Interval returned by [`interval`] and [`interval_at`].
376
///
377
/// This type allows you to wait on a sequence of instants with a certain
378
/// duration between each instant. Unlike calling [`sleep`] in a loop, this lets
379
/// you count the time spent between the calls to [`sleep`] as well.
380
///
381
/// An `Interval` can be turned into a `Stream` with [`IntervalStream`].
382
///
383
/// [`IntervalStream`]: https://docs.rs/tokio-stream/latest/tokio_stream/wrappers/struct.IntervalStream.html
384
/// [`sleep`]: crate::time::sleep()
385
#[derive(Debug)]
386
pub struct Interval {
387
    /// Future that completes the next time the `Interval` yields a value.
388
    delay: Pin<Box<Sleep>>,
389
390
    /// The duration between values yielded by `Interval`.
391
    period: Duration,
392
393
    /// The strategy `Interval` should use when a tick is missed.
394
    missed_tick_behavior: MissedTickBehavior,
395
396
    #[cfg(all(tokio_unstable, feature = "tracing"))]
397
    resource_span: tracing::Span,
398
}
399
400
impl Interval {
401
    /// Completes when the next instant in the interval has been reached.
402
    ///
403
    /// # Cancel safety
404
    ///
405
    /// This method is cancel safe. If `tick` is used as a branch in
406
    /// [`tokio::select!`](crate::select) and another branch completes first,
407
    /// then no tick has been consumed.
408
    ///
409
    /// # Examples
410
    ///
411
    /// ```
412
    /// use tokio::time;
413
    ///
414
    /// use std::time::Duration;
415
    ///
416
    /// # #[tokio::main(flavor = "current_thread")]
417
    /// # async fn main() {
418
    /// let mut interval = time::interval(Duration::from_millis(10));
419
    ///
420
    /// interval.tick().await;
421
    /// // approximately 0ms have elapsed. The first tick completes immediately.
422
    /// interval.tick().await;
423
    /// interval.tick().await;
424
    ///
425
    /// // approximately 20ms have elapsed.
426
    /// # }
427
    /// ```
428
0
    pub async fn tick(&mut self) -> Instant {
429
        #[cfg(all(tokio_unstable, feature = "tracing"))]
430
        let resource_span = self.resource_span.clone();
431
        #[cfg(all(tokio_unstable, feature = "tracing"))]
432
        let instant = trace::async_op(
433
            || poll_fn(|cx| self.poll_tick(cx)),
434
            resource_span,
435
            "Interval::tick",
436
            "poll_tick",
437
            false,
438
        );
439
        #[cfg(not(all(tokio_unstable, feature = "tracing")))]
440
0
        let instant = poll_fn(|cx| self.poll_tick(cx));
441
442
0
        instant.await
443
0
    }
444
445
    /// Polls for the next instant in the interval to be reached.
446
    ///
447
    /// This method can return the following values:
448
    ///
449
    ///  * `Poll::Pending` if the next instant has not yet been reached.
450
    ///  * `Poll::Ready(instant)` if the next instant has been reached.
451
    ///
452
    /// When this method returns `Poll::Pending`, the current task is scheduled
453
    /// to receive a wakeup when the instant has elapsed. Note that on multiple
454
    /// calls to `poll_tick`, only the [`Waker`](std::task::Waker) from the
455
    /// [`Context`] passed to the most recent call is scheduled to receive a
456
    /// wakeup.
457
0
    pub fn poll_tick(&mut self, cx: &mut Context<'_>) -> Poll<Instant> {
458
        // Wait for the delay to be done
459
0
        ready!(Pin::new(&mut self.delay).poll(cx));
460
461
        // Get the time when we were scheduled to tick
462
0
        let timeout = self.delay.deadline();
463
464
0
        let now = Instant::now();
465
466
        // If a tick was not missed, and thus we are being called before the
467
        // next tick is due, just schedule the next tick normally, one `period`
468
        // after `timeout`
469
        //
470
        // However, if a tick took excessively long and we are now behind,
471
        // schedule the next tick according to how the user specified with
472
        // `MissedTickBehavior`
473
0
        let next = if now > timeout + Duration::from_millis(5) {
474
0
            self.missed_tick_behavior
475
0
                .next_timeout(timeout, now, self.period)
476
        } else {
477
0
            timeout
478
0
                .checked_add(self.period)
479
0
                .unwrap_or_else(Instant::far_future)
480
        };
481
482
        // When we arrive here, the internal delay returned `Poll::Ready`.
483
        // Reset the delay but do not register it. It should be registered with
484
        // the next call to [`poll_tick`].
485
0
        self.delay.as_mut().reset_without_timer(next);
486
487
        // Return the time when we were scheduled to tick
488
0
        Poll::Ready(timeout)
489
0
    }
490
491
    /// Resets the interval to complete one period after the current time.
492
    ///
493
    /// This method ignores [`MissedTickBehavior`] strategy.
494
    ///
495
    /// This is equivalent to calling `reset_at(Instant::now() + period)`.
496
    ///
497
    /// # Examples
498
    ///
499
    /// ```
500
    /// use tokio::time;
501
    ///
502
    /// use std::time::Duration;
503
    ///
504
    /// # #[tokio::main(flavor = "current_thread")]
505
    /// # async fn main() {
506
    /// let mut interval = time::interval(Duration::from_millis(100));
507
    ///
508
    /// interval.tick().await;
509
    ///
510
    /// time::sleep(Duration::from_millis(50)).await;
511
    /// interval.reset();
512
    ///
513
    /// interval.tick().await;
514
    /// interval.tick().await;
515
    ///
516
    /// // approximately 250ms have elapsed.
517
    /// # }
518
    /// ```
519
0
    pub fn reset(&mut self) {
520
0
        self.delay.as_mut().reset(Instant::now() + self.period);
521
0
    }
522
523
    /// Resets the interval immediately.
524
    ///
525
    /// This method ignores [`MissedTickBehavior`] strategy.
526
    ///
527
    /// This is equivalent to calling `reset_at(Instant::now())`.
528
    ///
529
    /// # Examples
530
    ///
531
    /// ```
532
    /// use tokio::time;
533
    ///
534
    /// use std::time::Duration;
535
    ///
536
    /// # #[tokio::main(flavor = "current_thread")]
537
    /// # async fn main() {
538
    /// let mut interval = time::interval(Duration::from_millis(100));
539
    ///
540
    /// interval.tick().await;
541
    ///
542
    /// time::sleep(Duration::from_millis(50)).await;
543
    /// interval.reset_immediately();
544
    ///
545
    /// interval.tick().await;
546
    /// interval.tick().await;
547
    ///
548
    /// // approximately 150ms have elapsed.
549
    /// # }
550
    /// ```
551
0
    pub fn reset_immediately(&mut self) {
552
0
        self.delay.as_mut().reset(Instant::now());
553
0
    }
554
555
    /// Resets the interval after the specified [`std::time::Duration`].
556
    ///
557
    /// This method ignores [`MissedTickBehavior`] strategy.
558
    ///
559
    /// This is equivalent to calling `reset_at(Instant::now() + after)`.
560
    ///
561
    /// # Examples
562
    ///
563
    /// ```
564
    /// use tokio::time;
565
    ///
566
    /// use std::time::Duration;
567
    ///
568
    /// # #[tokio::main(flavor = "current_thread")]
569
    /// # async fn main() {
570
    /// let mut interval = time::interval(Duration::from_millis(100));
571
    /// interval.tick().await;
572
    ///
573
    /// time::sleep(Duration::from_millis(50)).await;
574
    ///
575
    /// let after = Duration::from_millis(20);
576
    /// interval.reset_after(after);
577
    ///
578
    /// interval.tick().await;
579
    /// interval.tick().await;
580
    ///
581
    /// // approximately 170ms have elapsed.
582
    /// # }
583
    /// ```
584
0
    pub fn reset_after(&mut self, after: Duration) {
585
0
        self.delay.as_mut().reset(Instant::now() + after);
586
0
    }
587
588
    /// Resets the interval to a [`crate::time::Instant`] deadline.
589
    ///
590
    /// Sets the next tick to expire at the given instant. If the instant is in
591
    /// the past, then the [`MissedTickBehavior`] strategy will be used to
592
    /// catch up. If the instant is in the future, then the next tick will
593
    /// complete at the given instant, even if that means that it will sleep for
594
    /// longer than the duration of this [`Interval`]. If the [`Interval`] had
595
    /// any missed ticks before calling this method, then those are discarded.
596
    ///
597
    /// # Examples
598
    ///
599
    /// ```
600
    /// use tokio::time::{self, Instant};
601
    ///
602
    /// use std::time::Duration;
603
    ///
604
    /// # #[tokio::main(flavor = "current_thread")]
605
    /// # async fn main() {
606
    /// let mut interval = time::interval(Duration::from_millis(100));
607
    /// interval.tick().await;
608
    ///
609
    /// time::sleep(Duration::from_millis(50)).await;
610
    ///
611
    /// let deadline = Instant::now() + Duration::from_millis(30);
612
    /// interval.reset_at(deadline);
613
    ///
614
    /// interval.tick().await;
615
    /// interval.tick().await;
616
    ///
617
    /// // approximately 180ms have elapsed.
618
    /// # }
619
    /// ```
620
0
    pub fn reset_at(&mut self, deadline: Instant) {
621
0
        self.delay.as_mut().reset(deadline);
622
0
    }
623
624
    /// Returns the [`MissedTickBehavior`] strategy currently being used.
625
0
    pub fn missed_tick_behavior(&self) -> MissedTickBehavior {
626
0
        self.missed_tick_behavior
627
0
    }
628
629
    /// Sets the [`MissedTickBehavior`] strategy that should be used.
630
0
    pub fn set_missed_tick_behavior(&mut self, behavior: MissedTickBehavior) {
631
0
        self.missed_tick_behavior = behavior;
632
0
    }
633
634
    /// Returns the period of the interval.
635
0
    pub fn period(&self) -> Duration {
636
0
        self.period
637
0
    }
638
}