aboutsummaryrefslogtreecommitdiff
path: root/src/time/interval.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/time/interval.rs')
-rw-r--r--src/time/interval.rs112
1 files changed, 109 insertions, 3 deletions
diff --git a/src/time/interval.rs b/src/time/interval.rs
index ea8b393..48f81af 100644
--- a/src/time/interval.rs
+++ b/src/time/interval.rs
@@ -2,10 +2,10 @@ use crate::future::poll_fn;
use crate::time::{sleep_until, Duration, Instant, Sleep};
use crate::util::trace;
+use std::future::Future;
use std::panic::Location;
use std::pin::Pin;
use std::task::{Context, Poll};
-use std::{convert::TryInto, future::Future};
/// Creates new [`Interval`] that yields with interval of `period`. The first
/// tick completes immediately. The default [`MissedTickBehavior`] is
@@ -387,7 +387,7 @@ impl Default for MissedTickBehavior {
/// An `Interval` can be turned into a `Stream` with [`IntervalStream`].
///
/// [`IntervalStream`]: https://docs.rs/tokio-stream/latest/tokio_stream/wrappers/struct.IntervalStream.html
-/// [`sleep`]: crate::time::sleep
+/// [`sleep`]: crate::time::sleep()
#[derive(Debug)]
pub struct Interval {
/// Future that completes the next time the `Interval` yields a value.
@@ -482,7 +482,10 @@ impl Interval {
timeout + self.period
};
- self.delay.as_mut().reset(next);
+ // When we arrive here, the internal delay returned `Poll::Ready`.
+ // Reset the delay but do not register it. It should be registered with
+ // the next call to [`poll_tick`].
+ self.delay.as_mut().reset_without_reregister(next);
// Return the time when we were scheduled to tick
Poll::Ready(timeout)
@@ -492,6 +495,8 @@ impl Interval {
///
/// This method ignores [`MissedTickBehavior`] strategy.
///
+ /// This is equivalent to calling `reset_at(Instant::now() + period)`.
+ ///
/// # Examples
///
/// ```
@@ -518,6 +523,107 @@ impl Interval {
self.delay.as_mut().reset(Instant::now() + self.period);
}
+ /// Resets the interval immediately.
+ ///
+ /// This method ignores [`MissedTickBehavior`] strategy.
+ ///
+ /// This is equivalent to calling `reset_at(Instant::now())`.
+ ///
+ /// # 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_immediately();
+ ///
+ /// interval.tick().await;
+ /// interval.tick().await;
+ ///
+ /// // approximately 150ms have elapsed.
+ /// }
+ /// ```
+ pub fn reset_immediately(&mut self) {
+ self.delay.as_mut().reset(Instant::now());
+ }
+
+ /// Resets the interval after the specified [`std::time::Duration`].
+ ///
+ /// This method ignores [`MissedTickBehavior`] strategy.
+ ///
+ /// This is equivalent to calling `reset_at(Instant::now() + after)`.
+ ///
+ /// # 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;
+ ///
+ /// let after = Duration::from_millis(20);
+ /// interval.reset_after(after);
+ ///
+ /// interval.tick().await;
+ /// interval.tick().await;
+ ///
+ /// // approximately 170ms have elapsed.
+ /// }
+ /// ```
+ pub fn reset_after(&mut self, after: Duration) {
+ self.delay.as_mut().reset(Instant::now() + after);
+ }
+
+ /// Resets the interval to a [`crate::time::Instant`] deadline.
+ ///
+ /// Sets the next tick to expire at the given instant. If the instant is in
+ /// the past, then the [`MissedTickBehavior`] strategy will be used to
+ /// catch up. If the instant is in the future, then the next tick will
+ /// complete at the given instant, even if that means that it will sleep for
+ /// longer than the duration of this [`Interval`]. If the [`Interval`] had
+ /// any missed ticks before calling this method, then those are discarded.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use tokio::time::{self, Instant};
+ ///
+ /// 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;
+ ///
+ /// let deadline = Instant::now() + Duration::from_millis(30);
+ /// interval.reset_at(deadline);
+ ///
+ /// interval.tick().await;
+ /// interval.tick().await;
+ ///
+ /// // approximately 180ms have elapsed.
+ /// }
+ /// ```
+ pub fn reset_at(&mut self, deadline: Instant) {
+ self.delay.as_mut().reset(deadline);
+ }
+
/// Returns the [`MissedTickBehavior`] strategy currently being used.
pub fn missed_tick_behavior(&self) -> MissedTickBehavior {
self.missed_tick_behavior