Guide to the AsyncDrop pattern for async cleanup in Rust. Use when working with AsyncDropGuard, implementing AsyncDrop trait, or handling async resource cleanup.
The AsyncDrop pattern enables async cleanup for types that hold resources requiring asynchronous teardown (network connections, file handles, background tasks, etc.).
Rust's Drop trait is synchronous, but sometimes cleanup needs to be async. The AsyncDrop pattern solves this by:
AsyncDropGuard<T>async_drop().await calls// Creating
let mut guard = AsyncDropGuard::new(my_value);
// Using (transparent via Deref)
guard.do_something();
// Cleanup (REQUIRED before dropping)
guard.async_drop().await?;
#[async_trait]
pub trait AsyncDrop {
type Error: Debug;
async fn async_drop_impl(&mut self) -> Result<(), Self::Error>;
}
| Rule | Description |
|------|-------------|
| Always call async_drop() | Every AsyncDropGuard must have async_drop() called |
| Factory methods return guards | fn new() -> AsyncDropGuard<Self>, never plain Self |
| Types with guard members impl AsyncDrop | Delegate to member async_drops |
| Use the macro when possible | with_async_drop_2! handles cleanup automatically |
| Panics are exceptions | It's OK to skip async_drop on panic paths |
with_async_drop_2! MacroAutomatically calls async_drop() on scope exit:
let resource = get_resource().await?;
with_async_drop_2!(resource, {
// Use resource here
resource.do_work().await?;
Ok(result)
})
Implementation: crates/utils/src/async_drop/
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer