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:
- Call
tokio::spawnfromDropto clean up in the background. - 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.