4

I have an app using #[tokio::main], that creates several resources on AWS in one of its tasks. I've implemented cleaning up those resources in Drop handlers. However those cleanup functions are async, so I am using block_on to ensure they run synchronously before returning from drop.

use futures::executor::block_on;

struct EventQueue(pub String);

impl Drop for EventQueue {
    fn drop(&mut self) {
        block_on(delete_queue(&self.0))
    }
}

pub async fn delete_queue(queue_url: &str) {
    let sqs = rusoto_sqs::SqsClient::new(REGION);
    sqs.delete_queue(DeleteQueueRequest {
        queue_url: queue_url.to_string(),
    })
    .await
    .unwrap();
}

The main function doesn't return until a signal::ctrl_c().await.unwrap(); completes, after which I think the Tokio runtime is dropped, and the spawned tasks are cancelled. I believe the interaction with block_on is failing because the runtime is no longer usable.

Here's the panic output.

Matt Joiner
  • 112,946
  • 110
  • 377
  • 526

2 Answers2

0

Implementing async destructor is very tricky and some work have been done here, but not running drop is not considered as a bug, "Exiting without calling destructors".

Stargateur
  • 24,473
  • 8
  • 65
  • 91
0

I found that using tokio::select! in tokio 0.2.11. prevented the panics, and had the desired behaviour. I think because select! cancels the other futures before the runtime goes out of scope.

Matt Joiner
  • 112,946
  • 110
  • 377
  • 526