Rename Sleep to Delay (#270)

This patch renames `Sleep` from tokio-timer and the tokio facade to
`Delay`. Given that the future does not actually put anything to sleep,
the `Delay` name feels more appropriate.

Fixes #263
This commit is contained in:
Carl Lerche
2018-03-30 14:21:48 -07:00
committed by GitHub
parent baa2502ec6
commit ea172537aa
12 changed files with 220 additions and 224 deletions
+4 -4
View File
@@ -3,7 +3,7 @@
//! This module provides a number of types for executing code after a set period
//! of time.
//!
//! * [`Sleep`][Sleep] is a future that does no work and completes at a specific `Instant`
//! * [`Delay`][Delay] is a future that does no work and completes at a specific `Instant`
//! in time.
//!
//! * [`Interval`][Interval] is a stream yielding a value at a fixed period. It
@@ -28,14 +28,14 @@
//!
//! ```
//! use tokio::prelude::*;
//! use tokio::timer::Sleep;
//! use tokio::timer::Delay;
//!
//! use std::time::{Duration, Instant};
//!
//! let when = Instant::now() + Duration::from_millis(100);
//!
//! tokio::run({
//! Sleep::new(when)
//! Delay::new(when)
//! .map_err(|e| panic!("timer failed; err={:?}", e))
//! .and_then(|_| {
//! println!("Hello world!");
@@ -81,5 +81,5 @@ pub use tokio_timer::{
Deadline,
DeadlineError,
Interval,
Sleep,
Delay,
};
+3 -3
View File
@@ -17,7 +17,7 @@ fn timer_with_runtime() {
let (tx, rx) = mpsc::channel();
tokio::run({
Sleep::new(when)
Delay::new(when)
.map_err(|e| panic!("unexpected error; err={:?}", e))
.and_then(move |_| {
assert!(Instant::now() >= when);
@@ -35,7 +35,7 @@ fn starving() {
let _ = env_logger::init();
struct Starve(Sleep, u64);
struct Starve(Delay, u64);
impl Future for Starve {
type Item = u64;
@@ -55,7 +55,7 @@ fn starving() {
}
let when = Instant::now() + Duration::from_millis(20);
let starve = Starve(Sleep::new(when), 0);
let starve = Starve(Delay::new(when), 0);
let (tx, rx) = mpsc::channel();
+6 -8
View File
@@ -1,6 +1,4 @@
//! Docs
use Sleep;
use Delay;
use futures::{Future, Poll, Async};
@@ -19,7 +17,7 @@ use std::time::Instant;
#[derive(Debug)]
pub struct Deadline<T> {
future: T,
sleep: Sleep,
delay: Delay,
}
/// Error returned by `Deadline` future.
@@ -43,13 +41,13 @@ impl<T> Deadline<T> {
/// Create a new `Deadline` that completes when `future` completes or when
/// `deadline` is reached.
pub fn new(future: T, deadline: Instant) -> Deadline<T> {
Deadline::new_with_sleep(future, Sleep::new(deadline))
Deadline::new_with_delay(future, Delay::new(deadline))
}
pub(crate) fn new_with_sleep(future: T, sleep: Sleep) -> Deadline<T> {
pub(crate) fn new_with_delay(future: T, delay: Delay) -> Deadline<T> {
Deadline {
future,
sleep,
delay,
}
}
@@ -84,7 +82,7 @@ where T: Future,
}
// Now check the timer
match self.sleep.poll() {
match self.delay.poll() {
Ok(Async::NotReady) => Ok(Async::NotReady),
Ok(Async::Ready(_)) => {
Err(DeadlineError::elapsed())
@@ -7,40 +7,38 @@ use std::time::Instant;
/// A future that completes at a specified instant in time.
///
/// Instances of `Sleep` perform no work and complete with `()` once the
/// Instances of `Delay` perform no work and complete with `()` once the
/// specified deadline has been reached.
///
/// `Sleep` has a resolution of one millisecond and should not be used for tasks
/// `Delay` has a resolution of one millisecond and should not be used for tasks
/// that require high-resolution timers.
///
/// [`new`]: #method.new
#[derive(Debug)]
pub struct Sleep {
pub struct Delay {
/// The instant at which the future completes.
deadline: Instant,
/// The link between the `Sleep` instance at the timer that drives it.
/// The link between the `Delay` instance at the timer that drives it.
///
/// When `Sleep` is created with `new`, this is initialized to `None` and is
/// When `Delay` is created with `new`, this is initialized to `None` and is
/// lazily set in `poll`. When `poll` is called, the default for the current
/// execution context is used (obtained via `Handle::current`).
///
/// When `sleep` is created with `new_with_registration`, the value is set.
/// When `delay` is created with `new_with_registration`, the value is set.
///
/// Once `registration` is set to `Some`, it is never changed.
registration: Option<Registration>,
}
// ===== impl Sleep =====
impl Sleep {
/// Create a new `Sleep` instance that elapses at `deadline`.
impl Delay {
/// Create a new `Delay` instance that elapses at `deadline`.
///
/// Only millisecond level resolution is guaranteed. There is no guarantee
/// as to how the sub-millisecond portion of `deadline` will be handled.
/// `Sleep` should not be used for high-resolution timer use cases.
pub fn new(deadline: Instant) -> Sleep {
Sleep {
/// `Delay` should not be used for high-resolution timer use cases.
pub fn new(deadline: Instant) -> Delay {
Delay {
deadline,
registration: None,
}
@@ -48,9 +46,9 @@ impl Sleep {
pub(crate) fn new_with_registration(
deadline: Instant,
registration: Registration) -> Sleep
registration: Registration) -> Delay
{
Sleep {
Delay {
deadline,
registration: Some(registration),
}
@@ -61,18 +59,18 @@ impl Sleep {
self.deadline
}
/// Returns true if the `Sleep` has elapsed
/// Returns true if the `Delay` has elapsed
///
/// A `Sleep` is elapsed when the requested duration has elapsed.
/// A `Delay` is elapsed when the requested duration has elapsed.
pub fn is_elapsed(&self) -> bool {
self.registration.as_ref()
.map(|r| r.is_elapsed())
.unwrap_or(false)
}
/// Reset the `Sleep` instance to a new deadline.
/// Reset the `Delay` instance to a new deadline.
///
/// Calling this function allows changing the instant at which the `Sleep`
/// Calling this function allows changing the instant at which the `Delay`
/// future completes without having to create new associated state.
///
/// This function can be called both before and after the future has
@@ -85,7 +83,7 @@ impl Sleep {
}
}
/// Register the sleep with the timer instance for the current execution
/// Register the delay with the timer instance for the current execution
/// context.
fn register(&mut self) {
if self.registration.is_some() {
@@ -96,12 +94,12 @@ impl Sleep {
}
}
impl Future for Sleep {
impl Future for Delay {
type Item = ();
type Error = Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
// Ensure the `Sleep` instance is associated with a timer.
// Ensure the `Delay` instance is associated with a timer.
self.register();
self.registration.as_ref().unwrap()
+10 -10
View File
@@ -1,4 +1,4 @@
use Sleep;
use Delay;
use futures::{Future, Stream, Poll};
@@ -8,7 +8,7 @@ use std::time::{Instant, Duration};
#[derive(Debug)]
pub struct Interval {
/// Future that completes the next time the `Interval` yields a value.
sleep: Sleep,
delay: Delay,
/// The duration between values yielded by `Interval`.
duration: Duration,
@@ -26,12 +26,12 @@ impl Interval {
pub fn new(at: Instant, duration: Duration) -> Interval {
assert!(duration > Duration::new(0, 0), "`duration` must be non-zero.");
Interval::new_with_sleep(Sleep::new(at), duration)
Interval::new_with_delay(Delay::new(at), duration)
}
pub(crate) fn new_with_sleep(sleep: Sleep, duration: Duration) -> Interval {
pub(crate) fn new_with_delay(delay: Delay, duration: Duration) -> Interval {
Interval {
sleep,
delay,
duration,
}
}
@@ -42,15 +42,15 @@ impl Stream for Interval {
type Error = ::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
// Wait for the sleep to be done
let _ = try_ready!(self.sleep.poll());
// Wait for the delay to be done
let _ = try_ready!(self.delay.poll());
// Get the `now` by looking at the `sleep` deadline
let now = self.sleep.deadline();
// Get the `now` by looking at the `delay` deadline
let now = self.delay.deadline();
// The next interval value is `duration` after the one that just
// yielded.
self.sleep.reset(now + self.duration);
self.delay.reset(now + self.duration);
// Return the current instant
Ok(Some(now).into())
+5 -5
View File
@@ -2,7 +2,7 @@
//!
//! This crate provides a number of utilities for working with periods of time:
//!
//! * [`Sleep`]: A future that completes at a specified instant in time.
//! * [`Delay`]: A future that completes at a specified instant in time.
//!
//! * [`Interval`] A stream that yields at fixed time intervals.
//!
@@ -10,10 +10,10 @@
//! instant in time, erroring if the future takes too long.
//!
//! These three types are backed by a [`Timer`] instance. In order for
//! [`Sleep`], [`Interval`], and [`Deadline`] to function, the associated
//! [`Delay`], [`Interval`], and [`Deadline`] to function, the associated
//! [`Timer`] instance must be running on some thread.
//!
//! [`Sleep`]: struct.Sleep.html
//! [`Delay`]: struct.Delay.html
//! [`Deadline`]: struct.Deadline.html
//! [`Interval`]: struct.Interval.html
//! [`Timer`]: timer/struct.Timer.html
@@ -30,12 +30,12 @@ pub mod timer;
mod atomic;
mod deadline;
mod delay;
mod error;
mod interval;
mod sleep;
pub use self::deadline::{Deadline, DeadlineError};
pub use self::delay::Delay;
pub use self::error::Error;
pub use self::interval::Interval;
pub use self::timer::{Timer, with_default};
pub use self::sleep::Sleep;
+5 -5
View File
@@ -13,7 +13,7 @@ use std::sync::atomic::Ordering::SeqCst;
use std::time::Instant;
use std::u64;
/// Internal state shared between a `Sleep` instance and the timer.
/// Internal state shared between a `Delay` instance and the timer.
///
/// This struct is used as a node in two intrusive data structures:
///
@@ -27,7 +27,7 @@ use std::u64;
#[derive(Debug)]
pub(crate) struct Entry {
/// Timer internals. Using a weak pointer allows the timer to shutdown
/// without all `Sleep` instances having completed.
/// without all `Delay` instances having completed.
inner: Weak<Inner>,
/// Task to notify once the deadline is reached.
@@ -49,7 +49,7 @@ pub(crate) struct Entry {
/// counter.
///
/// One might think that it would be easier to just not create the `Entry`.
/// The problem is that `Sleep` expects creating a `Registration` to always
/// The problem is that `Delay` expects creating a `Registration` to always
/// return a `Registration` instance. This simplifying factor allows it to
/// improve the struct layout. To do this, we must always allocate the node.
counted: bool,
@@ -66,8 +66,8 @@ pub(crate) struct Entry {
/// When the entry expires, relative to the `start` of the timer
/// (Inner::start). This is only used by the timer.
///
/// A `Sleep` instance can be reset to a different deadline by the thread
/// that owns the `Sleep` instance. In this case, the timer thread will not
/// A `Delay` instance can be reset to a different deadline by the thread
/// that owns the `Delay` instance. In this case, the timer thread will not
/// immediately know that this has happened. The timer thread must know the
/// last deadline that it saw as it uses this value to locate the entry in
/// its wheel.
+11 -11
View File
@@ -1,4 +1,4 @@
use {Error, Sleep, Deadline, Interval};
use {Error, Delay, Deadline, Interval};
use timer::{Registration, Inner};
use tokio_executor::Enter;
@@ -9,7 +9,7 @@ use std::time::{Duration, Instant};
/// Handle to timer instance.
///
/// The `Handle` allows creating `Sleep` instances that are driven by the
/// The `Handle` allows creating `Delay` instances that are driven by the
/// associated timer.
///
/// A `Handle` is obtained by calling [`Timer::handle`].
@@ -25,14 +25,14 @@ thread_local!(static CURRENT_TIMER: RefCell<Option<Handle>> = RefCell::new(None)
/// Set the default timer for the duration of the closure.
///
/// From within the closure, [`Sleep`] instances that are created via
/// [`Sleep::new`] can be used.
/// From within the closure, [`Delay`] instances that are created via
/// [`Delay::new`] can be used.
///
/// # Panics
///
/// This function panics if there already is a default timer set.
///
/// [`Sleep`]: ../struct.Sleep.html
/// [`Delay`]: ../struct.Delay.html
pub fn with_default<F, R>(handle: &Handle, enter: &mut Enter, f: F) -> R
where F: FnOnce(&mut Enter) -> R
{
@@ -77,7 +77,7 @@ impl Handle {
///
/// This function should only be called from within the context of
/// [`with_default`]. Calling this function from outside of this context
/// will return a `Handle` that does not reference a timer. `Sleep`
/// will return a `Handle` that does not reference a timer. `Delay`
/// instances created with this handle will error.
///
/// [`with_default`]: ../fn.with_default.html
@@ -86,21 +86,21 @@ impl Handle {
.unwrap_or(Handle { inner: Weak::new() })
}
/// Create a `Sleep` driven by this handle's associated `Timer`.
pub fn sleep(&self, deadline: Instant) -> Sleep {
/// Create a `Delay` driven by this handle's associated `Timer`.
pub fn delay(&self, deadline: Instant) -> Delay {
let registration = Registration::new_with_handle(deadline, self.clone());
Sleep::new_with_registration(deadline, registration)
Delay::new_with_registration(deadline, registration)
}
/// Create a `Deadline` driven by this handle's associated `Timer`.
pub fn deadline<T>(&self, future: T, deadline: Instant) -> Deadline<T> {
Deadline::new_with_sleep(future, self.sleep(deadline))
Deadline::new_with_delay(future, self.delay(deadline))
}
/// Create a new `Interval` that starts at `at` and yields every `duration`
/// interval after that.
pub fn interval(&self, at: Instant, duration: Duration) -> Interval {
Interval::new_with_sleep(self.sleep(at), duration)
Interval::new_with_delay(self.delay(at), duration)
}
/// Try to get a handle to the current timer.
+16 -16
View File
@@ -3,12 +3,12 @@
//! This module contains the types needed to run a timer.
//!
//! The [`Timer`] type runs the timer logic. It holds all the necessary state
//! to track all associated [`Sleep`] instances and delivering notifications
//! to track all associated [`Delay`] instances and delivering notifications
//! once the deadlines are reached.
//!
//! The [`Handle`] type is a reference to a [`Timer`] instance. This type is
//! `Clone`, `Send`, and `Sync`. This type is used to create instances of
//! [`Sleep`].
//! [`Delay`].
//!
//! The [`Now`] trait describes how to get an `Instance` representing the
//! current moment in time. [`SystemNow`] is the default implementation, where
@@ -23,7 +23,7 @@
//!
//! [`Timer`]: struct.Timer.html
//! [`Handle`]: struct.Handle.html
//! [`Sleep`]: ../struct.Sleep.html
//! [`Delay`]: ../struct.Delay.html
//! [`Now`]: trait.Now.html
//! [`Now::now`]: trait.Now.html#method.now
@@ -52,16 +52,16 @@ use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::usize;
/// Timer implementation that drives [`Sleep`], [`Interval`], and [`Deadline`].
/// Timer implementation that drives [`Delay`], [`Interval`], and [`Deadline`].
///
/// A `Timer` instance tracks the state necessary for managing time and
/// notifying the [`Sleep`] instances once their deadlines are reached.
/// notifying the [`Delay`] instances once their deadlines are reached.
///
/// It is expected that a single `Timer` instance manages many individual
/// `Sleep` instances. The `Timer` implementation is thread-safe and, as such,
/// `Delay` instances. The `Timer` implementation is thread-safe and, as such,
/// is able to handle callers from across threads.
///
/// Callers do not use `Timer` directly to create `Sleep` instances. Instead,
/// Callers do not use `Timer` directly to create `Delay` instances. Instead,
/// [`Handle`] is used. A handle for the timer instance is obtained by calling
/// [`handle`]. [`Handle`] is the type that implements `Clone` and is `Send +
/// Sync`.
@@ -73,9 +73,9 @@ use std::usize;
/// The `Timer` has a resolution of one millisecond. Any unit of time that falls
/// between milliseconds are rounded up to the next millisecond.
///
/// When the `Timer` instance is dropped, any outstanding `Sleep` instance that
/// When the `Timer` instance is dropped, any outstanding `Delay` instance that
/// has not elapsed will be notified with an error. At this point, calling
/// `poll` on the sleep instance will result in `Err` being returned.
/// `poll` on the `Delay` instance will result in `Err` being returned.
///
/// # Implementation
///
@@ -102,13 +102,13 @@ use std::usize;
/// * Level 5: 64 x ~12 day slots.
///
/// When the timer processes entries at level zero, it will notify all the
/// [`Sleep`] instances as their deadlines have been reached. For all higher
/// [`Delay`] instances as their deadlines have been reached. For all higher
/// levels, all entries will be redistributed across the wheel at the next level
/// down. Eventually, as time progresses, entries will `Sleep` instances will
/// down. Eventually, as time progresses, entries will `Delay` instances will
/// either be canceled (dropped) or their associated entries will reach level
/// zero and be notified.
///
/// [`Sleep`]: ../struct.Sleep.html
/// [`Delay`]: ../struct.Delay.html
/// [`Interval`]: ../struct.Interval.html
/// [`Deadline`]: ../struct.Deadline.html
/// [paper]: http://www.cs.columbia.edu/~nahum/w6998/papers/ton97-timing-wheels.pdf
@@ -172,7 +172,7 @@ pub(crate) struct Inner {
/// precision of 1 millisecond.
const NUM_LEVELS: usize = 6;
/// The maximum duration of a sleep
/// The maximum duration of a delay
const MAX_DURATION: u64 = 1 << (6 * NUM_LEVELS);
/// Maximum number of timeouts the system can handle concurrently.
@@ -187,7 +187,7 @@ where T: Park
/// thread.
///
/// Once the timer has been created, a handle can be obtained using
/// [`handle`]. The handle is used to create `Sleep` instances.
/// [`handle`]. The handle is used to create `Delay` instances.
///
/// Use `default` when constructing a `Timer` using the default `park`
/// instance.
@@ -236,7 +236,7 @@ where T: Park,
/// Returns a handle to the timer.
///
/// The `Handle` is how `Sleep` instances are created. The `Sleep` instances
/// The `Handle` is how `Delay` instances are created. The `Delay` instances
/// can either be created directly or the `Handle` instance can be passed to
/// `with_default`, setting the timer as the default timer for the execution
/// context.
@@ -250,7 +250,7 @@ where T: Park,
/// instance to make progress. This is where the work happens.
///
/// The `Timer` will use the `Park` instance that was specified in [`new`]
/// to block the current thread until the next `Sleep` instance elapses. One
/// to block the current thread until the next `Delay` instance elapses. One
/// call to `turn` results in at most one call to `park.park()`.
///
/// # Return
+1 -1
View File
@@ -8,7 +8,7 @@ use std::time::Instant;
/// Registration with a timer.
///
/// The association between a `Sleep` instance and a timer is done lazily in
/// The association between a `Delay` instance and a timer is done lazily in
/// `poll`
#[derive(Debug)]
pub(crate) struct Registration {
@@ -13,13 +13,13 @@ use futures::Future;
use std::time::{Duration, Instant};
#[test]
fn immediate_sleep() {
fn immediate_delay() {
mocked(|timer, time| {
// Create `Sleep` that elapsed immediately.
let mut sleep = Sleep::new(time.now());
// Create `Delay` that elapsed immediately.
let mut delay = Delay::new(time.now());
// Ready!
assert_ready!(sleep);
assert_ready!(delay);
// Turn the timer, it runs for the elapsed time
turn(timer, ms(1000));
@@ -30,37 +30,37 @@ fn immediate_sleep() {
}
#[test]
fn delayed_sleep_level_0() {
fn delayed_delay_level_0() {
for &i in &[1, 10, 60] {
mocked(|timer, time| {
// Create a `Sleep` that elapses in the future
let mut sleep = Sleep::new(time.now() + ms(i));
// Create a `Delay` that elapses in the future
let mut delay = Delay::new(time.now() + ms(i));
// The sleep has not elapsed.
assert_not_ready!(sleep);
// The delay has not elapsed.
assert_not_ready!(delay);
turn(timer, ms(1000));
assert_eq!(time.advanced(), ms(i));
assert_ready!(sleep);
assert_ready!(delay);
});
}
}
#[test]
fn sub_ms_delayed_sleep() {
fn sub_ms_delayed_delay() {
mocked(|timer, time| {
for _ in 0..5 {
let deadline = time.now()
+ Duration::from_millis(1)
+ Duration::new(0, 1);
let mut sleep = Sleep::new(deadline);
let mut delay = Delay::new(deadline);
assert_not_ready!(sleep);
assert_not_ready!(delay);
turn(timer, None);
assert_ready!(sleep);
assert_ready!(delay);
assert!(time.now() >= deadline);
@@ -70,38 +70,38 @@ fn sub_ms_delayed_sleep() {
}
#[test]
fn delayed_sleep_wrapping_level_0() {
fn delayed_delay_wrapping_level_0() {
mocked(|timer, time| {
turn(timer, ms(5));
assert_eq!(time.advanced(), ms(5));
let mut sleep = Sleep::new(time.now() + ms(60));
let mut delay = Delay::new(time.now() + ms(60));
assert_not_ready!(sleep);
assert_not_ready!(delay);
turn(timer, None);
assert_eq!(time.advanced(), ms(64));
assert_not_ready!(sleep);
assert_not_ready!(delay);
turn(timer, None);
assert_eq!(time.advanced(), ms(65));
assert_ready!(sleep);
assert_ready!(delay);
});
}
#[test]
fn timer_wrapping_with_higher_levels() {
mocked(|timer, time| {
// Set sleep to hit level 1
let mut s1 = Sleep::new(time.now() + ms(64));
// Set delay to hit level 1
let mut s1 = Delay::new(time.now() + ms(64));
assert_not_ready!(s1);
// Turn a bit
turn(timer, ms(5));
// Set timeout such that it will hit level 0, but wrap
let mut s2 = Sleep::new(time.now() + ms(60));
let mut s2 = Delay::new(time.now() + ms(60));
assert_not_ready!(s2);
// This should result in s1 firing
@@ -119,14 +119,14 @@ fn timer_wrapping_with_higher_levels() {
}
#[test]
fn sleep_with_deadline_in_past() {
fn delay_with_deadline_in_past() {
mocked(|timer, time| {
// Create `Sleep` that elapsed immediately.
let mut sleep = Sleep::new(time.now() - ms(100));
// Create `Delay` that elapsed immediately.
let mut delay = Delay::new(time.now() - ms(100));
// Even though the sleep expires in the past, it is not ready yet
// Even though the delay expires in the past, it is not ready yet
// because the timer must observe it.
assert_ready!(sleep);
assert_ready!(delay);
// Turn the timer, it runs for the elapsed time
turn(timer, ms(1000));
@@ -137,149 +137,149 @@ fn sleep_with_deadline_in_past() {
}
#[test]
fn delayed_sleep_level_1() {
fn delayed_delay_level_1() {
mocked(|timer, time| {
// Create a `Sleep` that elapses in the future
let mut sleep = Sleep::new(time.now() + ms(234));
// Create a `Delay` that elapses in the future
let mut delay = Delay::new(time.now() + ms(234));
// The sleep has not elapsed.
assert_not_ready!(sleep);
// The delay has not elapsed.
assert_not_ready!(delay);
// Turn the timer, this will wake up to cascade the timer down.
turn(timer, ms(1000));
assert_eq!(time.advanced(), ms(192));
// The sleep has not elapsed.
assert_not_ready!(sleep);
// The delay has not elapsed.
assert_not_ready!(delay);
// Turn the timer again
turn(timer, ms(1000));
assert_eq!(time.advanced(), ms(234));
// The sleep has elapsed.
assert_ready!(sleep);
// The delay has elapsed.
assert_ready!(delay);
});
mocked(|timer, time| {
// Create a `Sleep` that elapses in the future
let mut sleep = Sleep::new(time.now() + ms(234));
// Create a `Delay` that elapses in the future
let mut delay = Delay::new(time.now() + ms(234));
// The sleep has not elapsed.
assert_not_ready!(sleep);
// The delay has not elapsed.
assert_not_ready!(delay);
// Turn the timer with a smaller timeout than the cascade.
turn(timer, ms(100));
assert_eq!(time.advanced(), ms(100));
assert_not_ready!(sleep);
assert_not_ready!(delay);
// Turn the timer, this will wake up to cascade the timer down.
turn(timer, ms(1000));
assert_eq!(time.advanced(), ms(192));
// The sleep has not elapsed.
assert_not_ready!(sleep);
// The delay has not elapsed.
assert_not_ready!(delay);
// Turn the timer again
turn(timer, ms(1000));
assert_eq!(time.advanced(), ms(234));
// The sleep has elapsed.
assert_ready!(sleep);
// The delay has elapsed.
assert_ready!(delay);
});
}
#[test]
fn creating_sleep_outside_of_context() {
fn creating_delay_outside_of_context() {
let now = Instant::now();
// This creates a sleep outside of the context of a mock timer. This tests
// This creates a delay outside of the context of a mock timer. This tests
// that it will still expire.
let mut sleep = Sleep::new(now + ms(500));
let mut delay = Delay::new(now + ms(500));
mocked_with_now(now, |timer, time| {
// This registers the sleep with the timer
assert_not_ready!(sleep);
// This registers the delay with the timer
assert_not_ready!(delay);
// Wait some time... the timer is cascading
turn(timer, ms(1000));
assert_eq!(time.advanced(), ms(448));
assert_not_ready!(sleep);
assert_not_ready!(delay);
turn(timer, ms(1000));
assert_eq!(time.advanced(), ms(500));
// The sleep has elapsed
assert_ready!(sleep);
// The delay has elapsed
assert_ready!(delay);
});
}
#[test]
fn concurrently_set_two_timers_second_one_shorter() {
mocked(|timer, time| {
let mut sleep1 = Sleep::new(time.now() + ms(500));
let mut sleep2 = Sleep::new(time.now() + ms(200));
let mut delay1 = Delay::new(time.now() + ms(500));
let mut delay2 = Delay::new(time.now() + ms(200));
// The sleep has not elapsed
assert_not_ready!(sleep1);
assert_not_ready!(sleep2);
// The delay has not elapsed
assert_not_ready!(delay1);
assert_not_ready!(delay2);
// Sleep until a cascade
// Delay until a cascade
turn(timer, None);
assert_eq!(time.advanced(), ms(192));
// Sleep until the second timer.
// Delay until the second timer.
turn(timer, None);
assert_eq!(time.advanced(), ms(200));
// The shorter sleep fires
assert_ready!(sleep2);
assert_not_ready!(sleep1);
// The shorter delay fires
assert_ready!(delay2);
assert_not_ready!(delay1);
turn(timer, None);
assert_eq!(time.advanced(), ms(448));
assert_not_ready!(sleep1);
assert_not_ready!(delay1);
// Turn again, this time the time will advance to the second sleep
// Turn again, this time the time will advance to the second delay
turn(timer, None);
assert_eq!(time.advanced(), ms(500));
assert_ready!(sleep1);
assert_ready!(delay1);
})
}
#[test]
fn short_sleep() {
fn short_delay() {
mocked(|timer, time| {
// Create a `Sleep` that elapses in the future
let mut sleep = Sleep::new(time.now() + ms(1));
// Create a `Delay` that elapses in the future
let mut delay = Delay::new(time.now() + ms(1));
// The sleep has not elapsed.
assert_not_ready!(sleep);
// The delay has not elapsed.
assert_not_ready!(delay);
// Turn the timer, but not enough timee will go by.
turn(timer, None);
// The sleep has elapsed.
assert_ready!(sleep);
// The delay has elapsed.
assert_ready!(delay);
// The time has advanced to the point of the sleep elapsing.
// The time has advanced to the point of the delay elapsing.
assert_eq!(time.advanced(), ms(1));
})
}
#[test]
fn sorta_long_sleep() {
fn sorta_long_delay() {
const MIN_5: u64 = 5 * 60 * 1000;
mocked(|timer, time| {
// Create a `Sleep` that elapses in the future
let mut sleep = Sleep::new(time.now() + ms(MIN_5));
// Create a `Delay` that elapses in the future
let mut delay = Delay::new(time.now() + ms(MIN_5));
// The sleep has not elapsed.
assert_not_ready!(sleep);
// The delay has not elapsed.
assert_not_ready!(delay);
let cascades = &[
262_144,
@@ -291,27 +291,27 @@ fn sorta_long_sleep() {
turn(timer, None);
assert_eq!(time.advanced(), ms(elapsed));
assert_not_ready!(sleep);
assert_not_ready!(delay);
}
turn(timer, None);
assert_eq!(time.advanced(), ms(MIN_5));
// The sleep has elapsed.
assert_ready!(sleep);
// The delay has elapsed.
assert_ready!(delay);
})
}
#[test]
fn very_long_sleep() {
fn very_long_delay() {
const MO_5: u64 = 5 * 30 * 24 * 60 * 60 * 1000;
mocked(|timer, time| {
// Create a `Sleep` that elapses in the future
let mut sleep = Sleep::new(time.now() + ms(MO_5));
// Create a `Delay` that elapses in the future
let mut delay = Delay::new(time.now() + ms(MO_5));
// The sleep has not elapsed.
assert_not_ready!(sleep);
// The delay has not elapsed.
assert_not_ready!(delay);
let cascades = &[
12_884_901_888,
@@ -324,17 +324,17 @@ fn very_long_sleep() {
turn(timer, None);
assert_eq!(time.advanced(), ms(elapsed));
assert_not_ready!(sleep);
assert_not_ready!(delay);
}
// Turn the timer, but not enough time will go by.
turn(timer, None);
// The time has advanced to the point of the sleep elapsing.
// The time has advanced to the point of the delay elapsing.
assert_eq!(time.advanced(), ms(MO_5));
// The sleep has elapsed.
assert_ready!(sleep);
// The delay has elapsed.
assert_ready!(delay);
})
}
@@ -343,27 +343,27 @@ fn greater_than_max() {
const YR_5: u64 = 5 * 365 * 24 * 60 * 60 * 1000;
mocked(|timer, time| {
// Create a `Sleep` that elapses in the future
let mut sleep = Sleep::new(time.now() + ms(YR_5));
// Create a `Delay` that elapses in the future
let mut delay = Delay::new(time.now() + ms(YR_5));
assert_not_ready!(sleep);
assert_not_ready!(delay);
turn(timer, ms(0));
assert!(sleep.poll().is_err());
assert!(delay.poll().is_err());
})
}
#[test]
fn unpark_is_delayed() {
mocked(|timer, time| {
let mut sleep1 = Sleep::new(time.now() + ms(100));
let mut sleep2 = Sleep::new(time.now() + ms(101));
let mut sleep3 = Sleep::new(time.now() + ms(200));
let mut delay1 = Delay::new(time.now() + ms(100));
let mut delay2 = Delay::new(time.now() + ms(101));
let mut delay3 = Delay::new(time.now() + ms(200));
assert_not_ready!(sleep1);
assert_not_ready!(sleep2);
assert_not_ready!(sleep3);
assert_not_ready!(delay1);
assert_not_ready!(delay2);
assert_not_ready!(delay3);
time.park_for(ms(500));
@@ -371,9 +371,9 @@ fn unpark_is_delayed() {
assert_eq!(time.advanced(), ms(500));
assert_ready!(sleep1);
assert_ready!(sleep2);
assert_ready!(sleep3);
assert_ready!(delay1);
assert_ready!(delay2);
assert_ready!(delay3);
})
}
@@ -387,87 +387,87 @@ fn set_timeout_at_deadline_greater_than_max_timer() {
turn(timer, ms(YR_1));
}
let mut sleep = Sleep::new(time.now() + ms(1));
assert_not_ready!(sleep);
let mut delay = Delay::new(time.now() + ms(1));
assert_not_ready!(delay);
turn(timer, ms(1000));
assert_eq!(time.advanced(), Duration::from_millis(YR_5) + ms(1));
assert_ready!(sleep);
assert_ready!(delay);
});
}
#[test]
fn reset_future_sleep_before_fire() {
fn reset_future_delay_before_fire() {
mocked(|timer, time| {
let mut sleep = Sleep::new(time.now() + ms(100));
let mut delay = Delay::new(time.now() + ms(100));
assert_not_ready!(sleep);
assert_not_ready!(delay);
sleep.reset(time.now() + ms(200));
delay.reset(time.now() + ms(200));
turn(timer, None);
assert_eq!(time.advanced(), ms(192));
assert_not_ready!(sleep);
assert_not_ready!(delay);
turn(timer, None);
assert_eq!(time.advanced(), ms(200));
assert_ready!(sleep);
assert_ready!(delay);
});
}
#[test]
fn reset_past_sleep_before_turn() {
fn reset_past_delay_before_turn() {
mocked(|timer, time| {
let mut sleep = Sleep::new(time.now() + ms(100));
let mut delay = Delay::new(time.now() + ms(100));
assert_not_ready!(sleep);
assert_not_ready!(delay);
sleep.reset(time.now() + ms(80));
delay.reset(time.now() + ms(80));
turn(timer, None);
assert_eq!(time.advanced(), ms(64));
assert_not_ready!(sleep);
assert_not_ready!(delay);
turn(timer, None);
assert_eq!(time.advanced(), ms(80));
assert_ready!(sleep);
assert_ready!(delay);
});
}
#[test]
fn reset_past_sleep_before_fire() {
fn reset_past_delay_before_fire() {
mocked(|timer, time| {
let mut sleep = Sleep::new(time.now() + ms(100));
let mut delay = Delay::new(time.now() + ms(100));
assert_not_ready!(sleep);
assert_not_ready!(delay);
turn(timer, ms(10));
assert_not_ready!(sleep);
sleep.reset(time.now() + ms(80));
assert_not_ready!(delay);
delay.reset(time.now() + ms(80));
turn(timer, None);
assert_eq!(time.advanced(), ms(64));
assert_not_ready!(sleep);
assert_not_ready!(delay);
turn(timer, None);
assert_eq!(time.advanced(), ms(90));
assert_ready!(sleep);
assert_ready!(delay);
});
}
#[test]
fn reset_future_sleep_after_fire() {
fn reset_future_delay_after_fire() {
mocked(|timer, time| {
let mut sleep = Sleep::new(time.now() + ms(100));
let mut delay = Delay::new(time.now() + ms(100));
assert_not_ready!(sleep);
assert_not_ready!(delay);
turn(timer, ms(1000));
assert_eq!(time.advanced(), ms(64));
@@ -475,14 +475,14 @@ fn reset_future_sleep_after_fire() {
turn(timer, None);
assert_eq!(time.advanced(), ms(100));
assert_ready!(sleep);
assert_ready!(delay);
sleep.reset(time.now() + ms(10));
assert_not_ready!(sleep);
delay.reset(time.now() + ms(10));
assert_not_ready!(delay);
turn(timer, ms(1000));
assert_eq!(time.advanced(), ms(110));
assert_ready!(sleep);
assert_ready!(delay);
});
}
+6 -6
View File
@@ -56,7 +56,7 @@ fn hammer_complete() {
rng.gen_range(MIN_DELAY, MAX_DELAY));
exec.push({
handle.sleep(deadline)
handle.delay(deadline)
.and_then(move |_| {
let now = Instant::now();
assert!(now >= deadline, "deadline greater by {:?}", deadline - now);
@@ -120,8 +120,8 @@ fn hammer_cancel() {
let deadline = cmp::min(deadline1, deadline2);
let sleep = handle.sleep(deadline1);
let join = handle.deadline(sleep, deadline2);
let delay = handle.delay(deadline1);
let join = handle.deadline(delay, deadline2);
exec.push({
join
@@ -195,9 +195,9 @@ fn hammer_reset() {
rng.gen_range(MIN_DELAY, MAX_DELAY));
exec.push({
handle.sleep(deadline1)
// Select over a second sleep
.select2(handle.sleep(deadline2))
handle.delay(deadline1)
// Select over a second delay
.select2(handle.delay(deadline2))
.map_err(|e| panic!("boom; err={:?}", e))
.and_then(move |res| {
use futures::future::Either::*;