Following discussions related to Async Drop

I've encountered a problem at work where async drop might be helpful. But it's an experimental feature, so I'm a little hesitant to use it. I don't know if there are any footguns that I need to be aware of while using this feature, and searching on google and on this forum doesn't help much either. Are there any rust developers mailing lists/forums where I can find discussions related to this feature?

My suggestion is that you find a different solution.

Two common solutions are:

  1. Call tokio::spawn from Drop to clean up in the background.
  2. Use a scope to enforce cleanup instead of a destructor:
use std::panic::AssertUnwindSafe;

struct MyResource();

async fn get_resource() -> MyResource {
    todo!()
}
async fn cleanup_resource(res: MyResource) {
    todo!()
}

async fn with_resource<T>(f: impl AsyncFnOnce(&mut MyResource) -> T) -> T {
    let mut res = get_resource().await;
    let ret = futures::FutureExt::catch_unwind(AssertUnwindSafe(f(&mut res))).await;
    cleanup_resource(res).await;
    match ret {
        Ok(t) => t,
        Err(panic) => std::panic::resume_unwind(panic),
    }
}

and then you call

with_resource(|res| {
    do_stuff(res).await;
});
1 Like

So we have a daemon that we need to turn into a library. It spawns a bunch of tasks which do some work. Having our API return a future which our clients can execute looks like a good choice, because they can just drop the future to kill the daemon. (tokio_postgres does this as well). Inside this future we use a JoinSet for cleanup, and we would like to avoid doing unscoped spawns because if the client decides to restart the daemon for some reason, then there is a chance that the cleanup task might interfere with the new instance.