Паника при запуске асинхронного кода при удалении Rust Future
У меня есть приложение, использующее #[tokio::main]
, который создает несколько ресурсов на AWS в одной из своих задач. Я реализовал очистку этих ресурсов вDrop
обработчики. Однако эти функции очистки являются асинхронными, поэтому я используюblock_on
чтобы убедиться, что они работают синхронно, прежде чем вернуться из 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();
}
В main
функция не возвращается, пока signal::ctrl_c().await.unwrap();
завершается, после чего, я думаю, среда выполнения Tokio удаляется, а порожденные задачи отменяются. Я считаю, что взаимодействие сblock_on
дает сбой, потому что среда выполнения больше не используется.
Вот выход паники.
2 ответа
Я обнаружил, что используя tokio::select!
в токио 0.2.11. предотвратил панику и вел желаемое поведение. Я думаю потому чтоselect!
отменяет другие фьючерсы до того, как среда выполнения выйдет за пределы области видимости.
Реализация асинхронной деструктор очень сложно, и некоторые работы были сделаны здесь, но не работаетdrop
не считается ошибкой "Выход без вызова деструкторов".