Hasty Briefsbeta

Bilingual

Never Snooze a Future

6 days ago
  • #deadlocks
  • #async-rust
  • #futures
  • Snoozing in async Rust refers to a future that's ready to make progress but isn't being polled, leading to hangs and deadlocks.
  • Snoozing is distinct from cancellation and starvation, representing a bug where a future that requested a wakeup doesn't get polled.
  • Deadlocks ('futurelocks') are a clear consequence of snoozing, where a task stops polling a future it previously started, causing system hangs.
  • Examples include scenarios with `select!` by reference and buffered streams, where internal futures are snoozed, leading to deadlocks.
  • Thread cancellation in synchronous programming contrasts with future cancellation in async Rust, where Rust's drop mechanism allows cleaner resource cleanup.
  • Snoozing a future is akin to pausing a thread, risking deadlocks when the paused entity holds locks needed by other parts of the system.
  • Solutions to avoid snoozing include avoiding `select!` with references, using owned futures, and considering alternative patterns like `join_me_maybe`.
  • Stream methods like `.next()` and buffered streams pose snoozing risks, suggesting a need for clearer cancel safety definitions and possibly deprecating problematic patterns.
  • A proposed rule to prevent snoozing is to avoid pinning things in async functions, as pinning often indicates polling a future that isn't owned.
  • Advanced async Rust (implementing `Future` or `Stream`) requires careful review to ensure snooze-free behavior, emphasizing the principle: never snooze a future.