use crossbeam_channel::Sender;
use std::time::Duration;
use tokio::time;
struct Dropper {
sender: Sender<&'static str>,
}
impl Drop for Dropper {
fn drop(&mut self) {
self.sender.send("done").unwrap();
}
}
#[tokio::test(flavor = "multi_thread")]
async fn strict_drop_ordering() {
let (sender, receiver) = crossbeam_channel::bounded(10);
let dropper = Dropper { sender };
let handle = structured_spawn::spawn(async move {
let dropper = dropper;
time::sleep(Duration::from_millis(100)).await;
drop(dropper);
unreachable!("the future should time-out before the timer resolves");
});
assert!(receiver.try_recv().is_err());
let _ = time::timeout(Duration::from_millis(10), handle).await;
assert_eq!(receiver.try_recv().unwrap(), "done");
}
#[tokio::test(flavor = "multi_thread")]
async fn relaxed_drop_ordering() {
let (sender, receiver) = crossbeam_channel::bounded(10);
let dropper = Dropper { sender };
let handle = structured_spawn::spawn_relaxed(async move {
let dropper = dropper;
time::sleep(Duration::from_millis(100)).await;
drop(dropper); unreachable!("the future should time-out before the timer resolves");
});
let _ = time::timeout(Duration::from_millis(10), handle).await;
assert!(
receiver.try_recv().is_err(),
"cancellation might take a while to resolve"
);
assert_eq!(
receiver.recv().unwrap(),
"done",
"but cancellation is guaranteed to eventually resolve"
);
}