'How do I implement an async Drop in Rust?
I have an async fn
that returns a type, and want to implement Drop
on that type that calls another async
function. It's not clear how to do this, and I can't find anything in the docs. The most illuminating article I found is Asynchronous Destructors by withoutboats, but I don't really understand the reasoning, or where this feature is at.
Solution 1:[1]
It's not clear how to do this, and I can't find anything in the docs
That's because it's not possible; there is no "async Drop
". Drop
must be synchronous.
See also:
Solution 2:[2]
I've implemented an async drop using CancellationTokens
for a struct we use in our testing.
Note: This is currently just used in our test code, I wouldn't recommended it for any production code without some serious testing.
struct TestObj {
drop_token: CancellationToken,
dropped_token: CancellationToken
}
impl TestObj {
pub async fn new() -> Self {
let drop_token = CancellationToken::new();
let dropped_token = start_drop_watcher(&drop_token).await;
Self {
drop_token,
dropped_token
}
}
async fn start_drop_watcher(drop_token: &CancellationToken) -> CancellationToken {
let drop_child = drop_token.child_token();
let dropped_token = CancellationToken::new();
let dropped_child = dropped_token.child_token();
tokio::spawn(async move {
while !drop_child.is_cancelled() {
tokio::time::sleep(Duration::from_millis(100)).await;
}
// Do async cleanup logic here (probably with a timeout)
dropped_token.cancel();
});
dropped_child
}
}
impl Drop for TestObj {
fn drop(&mut self) {
self.drop_token.cancel();
while !self.dropped_token.is_cancelled() {
std::thread::sleep(Duration::from_millis(100));
}
}
}
It's also important you run your tests with multi-threading or this won't work.
#[tokio::test(flavor = "multi_thread")]
fn it_does_a_thing() {
assert!(true);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Shepmaster |
Solution 2 |