diff options
Diffstat (limited to 'src/time/interval.rs')
-rw-r--r-- | src/time/interval.rs | 112 |
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 |