mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-10-01 12:20:39 +00:00

Currently, the timer uses a `Now` trait to abstract the source of time. This allows time to be mocked out. However, the current implementation has a number of limitations as represented by #288 and #296. The main issues are that `Now` requires `&mut self` which prevents a value from being easily used in a concurrent environment. Also, when wanting to write code that is abstract over the source of time, generics get out of hand. This patch provides an alternate solution. A new type, `Clock` is provided which defaults to `Instant::now` as the source of time, but allows configuring the actual source using a new iteration of the `Now` trait. This time, `Now` is `Send + Sync + 'static`. Internally, `Clock` stores the now value in an `Arc<Now>` value, which introduces dynamism and allows `Clock` values to be cloned and be `Sync`. Also, the current clock can be set for the current execution context using the `with_default` pattern. Because using the `Instant::now` will be the most common case by far, it is special cased in order to avoid the need to allocate an `Arc` and use dynamic dispatch.
52 lines
901 B
Rust
52 lines
901 B
Rust
extern crate tokio_executor;
|
|
extern crate tokio_timer;
|
|
|
|
use tokio_timer::clock;
|
|
use tokio_timer::clock::*;
|
|
|
|
use std::time::Instant;
|
|
|
|
struct ConstNow(Instant);
|
|
|
|
impl Now for ConstNow {
|
|
fn now(&self) -> Instant {
|
|
self.0
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn default_clock() {
|
|
let a = Instant::now();
|
|
let b = clock::now();
|
|
let c = Clock::new().now();
|
|
|
|
assert!(a <= b);
|
|
assert!(b <= c);
|
|
}
|
|
|
|
#[test]
|
|
fn custom_clock() {
|
|
let now = ConstNow(Instant::now());
|
|
let clock = Clock::new_with_now(now);
|
|
|
|
let a = Instant::now();
|
|
let b = clock.now();
|
|
|
|
assert!(b <= a);
|
|
}
|
|
|
|
#[test]
|
|
fn execution_context() {
|
|
let now = ConstNow(Instant::now());
|
|
let clock = Clock::new_with_now(now);
|
|
|
|
let mut enter = tokio_executor::enter().unwrap();
|
|
|
|
with_default(&clock, &mut enter, |_| {
|
|
let a = Instant::now();
|
|
let b = clock::now();
|
|
|
|
assert!(b <= a);
|
|
});
|
|
}
|