structured-spawn 1.0.1

Structured async spawn implementations for Tokio
Documentation
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); // to guarantee the handle stays live
        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"
    );
}