From 51cc079a85cb52e5202f50267b08167f00132af9 Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Sat, 8 Aug 2026 20:08:12 +0800 Subject: [PATCH] queue: use notify_one so wakeups are never lost notify_waiters drops the notification when every worker is between its DB reads and registering notified(); a task enqueued in that window sat until a stale timer fired. notify_one stores a permit, so the next worker to wait wakes immediately and re-leases. stop() still wakes all workers with notify_waiters. --- crates/xmedia-bot/src/queue.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/xmedia-bot/src/queue.rs b/crates/xmedia-bot/src/queue.rs index d96d6b7..1ebfdff 100644 --- a/crates/xmedia-bot/src/queue.rs +++ b/crates/xmedia-bot/src/queue.rs @@ -203,9 +203,11 @@ impl PersistentTaskQueue { Ok(()) }) .await?; - // Wake every sleeping worker: with several workers the one that finds - // nothing due must not starve the newly inserted row. - self.notify.notify_waiters(); + // `notify_one` stores a permit when no worker is registered, so a + // notification fired between a worker's DB reads and its `notified()` + // registration is not lost (notify_waiters would drop it). The + // awakened worker re-leases and finds the new row. + self.notify.notify_one(); Ok(()) } @@ -400,7 +402,8 @@ impl QueueWorker { if let Err(e) = result { log::error!("queue reschedule failed: {e}"); } - self.notify.notify_waiters(); + // Same permit semantics as enqueue: never lose the wakeup. + self.notify.notify_one(); } }