fix(runtime): don't let orphaned timers block shutdown
A cooperatively-cancelled actor that was sleeping (or in a bounded wait) leaves its timer entry behind in the heap. The scheduler's shutdown check required "no pending timers", so a single orphaned far-future deadline kept the whole runtime alive until it fired — e.g. cancelling an actor mid sleep(30s) hung run() for 30s. A timer can only ever do useful work by waking a live actor, so once no actors are live every remaining entry is orphaned by definition. Drop the pending-timers condition from the shutdown check (live == 0 already implies nothing a timer could wake) and clear the heap on the way out.
This commit is contained in:
@@ -119,6 +119,13 @@ impl Timers {
|
||||
self.heap.is_empty()
|
||||
}
|
||||
|
||||
/// Drop all pending entries. Called by the scheduler when it has decided
|
||||
/// no actor is live: any remaining timer is orphaned and exists only to be
|
||||
/// discarded so it can't keep the runtime alive.
|
||||
pub fn clear(&mut self) {
|
||||
self.heap.clear();
|
||||
}
|
||||
|
||||
/// Soonest pending deadline, or `None` if the heap is empty.
|
||||
pub fn peek_deadline(&self) -> Option<Instant> {
|
||||
self.heap.peek().map(|r| r.0.deadline)
|
||||
|
||||
Reference in New Issue
Block a user