1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
use std::future::Future;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::{Duration, Instant};
use async_io::Timer;
use futures_lite::{future, FutureExt, StreamExt};
fn spawn<T: Send + 'static>(
f: impl Future<Output = T> + Send + 'static,
) -> impl Future<Output = T> + Send + 'static {
let (s, r) = async_channel::bounded(1);
thread::spawn(move || {
future::block_on(async {
s.send(f.await).await.ok();
})
});
Box::pin(async move { r.recv().await.unwrap() })
}
#[test]
fn smoke() {
future::block_on(async {
let start = Instant::now();
Timer::after(Duration::from_secs(1)).await;
assert!(start.elapsed() >= Duration::from_secs(1));
});
}
#[test]
fn interval() {
future::block_on(async {
let period = Duration::from_secs(1);
let jitter = Duration::from_millis(500);
let start = Instant::now();
let mut timer = Timer::interval(period);
timer.next().await;
let elapsed = start.elapsed();
assert!(elapsed >= period && elapsed - period < jitter);
timer.next().await;
let elapsed = start.elapsed();
assert!(elapsed >= period * 2 && elapsed - period * 2 < jitter);
});
}
#[test]
fn poll_across_tasks() {
future::block_on(async {
let start = Instant::now();
let (sender, receiver) = async_channel::bounded(1);
let task1 = spawn(async move {
let mut timer = Timer::after(Duration::from_secs(1));
async {
(&mut timer).await;
panic!("timer should not be ready")
}
.or(async {})
.await;
sender.send(timer).await.ok();
});
let task2 = spawn(async move {
let timer = receiver.recv().await.unwrap();
timer.await;
});
task1.await;
task2.await;
assert!(start.elapsed() >= Duration::from_secs(1));
});
}
#[test]
fn set() {
future::block_on(async {
let start = Instant::now();
let timer = Arc::new(Mutex::new(Timer::after(Duration::from_secs(10))));
thread::spawn({
let timer = timer.clone();
move || {
thread::sleep(Duration::from_secs(1));
timer.lock().unwrap().set_after(Duration::from_secs(2));
}
});
future::poll_fn(|cx| Pin::new(&mut *timer.lock().unwrap()).poll(cx)).await;
assert!(start.elapsed() >= Duration::from_secs(2));
assert!(start.elapsed() < Duration::from_secs(10));
});
}
|