From ce27ef8b9e43f7922e8ed1d3b8111c81c2d2d5a6 Mon Sep 17 00:00:00 2001 From: damocles Date: Mon, 1 Jun 2026 14:43:04 +0200 Subject: [PATCH] =?UTF-8?q?fix(#937):=20narrow=20skip=20to=20same-body=20p?= =?UTF-8?q?ending=20=E2=80=94=20different=20schedules=20can=20still=20enqu?= =?UTF-8?q?eue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hive-c0re/src/broker.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/hive-c0re/src/broker.rs b/hive-c0re/src/broker.rs index 020c07dd..5a701ce8 100644 --- a/hive-c0re/src/broker.rs +++ b/hive-c0re/src/broker.rs @@ -278,6 +278,27 @@ impl Broker { Ok(n > 0) } + /// Returns true when the recipient already has at least one + /// undelivered message from `sender` with exactly `body` in the + /// broker. Used by the scheduler to skip re-delivery of the same + /// scheduled prompt without blocking distinct schedules whose + /// bodies differ. + pub fn has_pending_with_body( + &self, + recipient: &str, + sender: &str, + body: &str, + ) -> Result { + let conn = self.conn.lock().unwrap(); + let n: i64 = conn.query_row( + "SELECT COUNT(*) FROM messages + WHERE recipient = ?1 AND sender = ?2 AND body = ?3 AND delivered_at IS NULL", + params![recipient, sender, body], + |row| row.get(0), + )?; + Ok(n > 0) + } + /// Long-poll variant of `recv_batch`: returns immediately if any /// row is pending (popping up to `max`); otherwise waits up to /// `timeout` for the broker to emit a `Sent { to: recipient }` @@ -1269,3 +1290,4 @@ mod tests { assert!(pop_one(broker, "bob").is_none()); } } +