'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