Skip to content

Commit

Permalink
time: add Interval::reset method (#4248)
Browse files Browse the repository at this point in the history
  • Loading branch information
oblique authored Nov 23, 2021
1 parent 2c0e5c9 commit 347c0cd
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
30 changes: 30 additions & 0 deletions tokio/src/time/interval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,36 @@ impl Interval {
Poll::Ready(timeout)
}

/// Resets the interval to complete one period after the current time.
///
/// This method ignores [`MissedTickBehavior`] strategy.
///
/// # Examples
///
/// ```
/// use tokio::time;
///
/// use std::time::Duration;
///
/// #[tokio::main]
/// async fn main() {
/// let mut interval = time::interval(Duration::from_millis(100));
///
/// interval.tick().await;
///
/// time::sleep(Duration::from_millis(50)).await;
/// interval.reset();
///
/// interval.tick().await;
/// interval.tick().await;
///
/// // approximately 250ms have elapsed.
/// }
/// ```
pub fn reset(&mut self) {
self.delay.as_mut().reset(Instant::now() + self.period);
}

/// Returns the [`MissedTickBehavior`] strategy currently being used.
pub fn missed_tick_behavior(&self) -> MissedTickBehavior {
self.missed_tick_behavior
Expand Down
36 changes: 36 additions & 0 deletions tokio/tests/time_interval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,42 @@ async fn skip() {
check_interval_poll!(i, start, 1800);
}

#[tokio::test(start_paused = true)]
async fn reset() {
let start = Instant::now();

// This is necessary because the timer is only so granular, and in order for
// all our ticks to resolve, the time needs to be 1ms ahead of what we
// expect, so that the runtime will see that it is time to resolve the timer
time::advance(ms(1)).await;

let mut i = task::spawn(time::interval_at(start, ms(300)));

check_interval_poll!(i, start, 0);

time::advance(ms(100)).await;
check_interval_poll!(i, start);

time::advance(ms(200)).await;
check_interval_poll!(i, start, 300);

time::advance(ms(100)).await;
check_interval_poll!(i, start);

i.reset();

time::advance(ms(250)).await;
check_interval_poll!(i, start);

time::advance(ms(50)).await;
// We add one because when using `reset` method, `Interval` adds the
// `period` from `Instant::now()`, which will always be off by one
check_interval_poll!(i, start, 701);

time::advance(ms(300)).await;
check_interval_poll!(i, start, 1001);
}

fn poll_next(interval: &mut task::Spawn<time::Interval>) -> Poll<Instant> {
interval.enter(|cx, mut interval| interval.poll_tick(cx))
}
Expand Down

0 comments on commit 347c0cd

Please sign in to comment.