parent
39482ea6cd
commit
970ee83a93
1 changed files with 29 additions and 3 deletions
|
|
@ -465,8 +465,9 @@ impl Broker {
|
|||
Ok(deliveries)
|
||||
}
|
||||
|
||||
/// Drain the per-recipient unacked-id list and mark every row
|
||||
/// `acked_at = NOW`. Fired by the harness after `TurnOutcome::Ok`.
|
||||
/// Mark every row in the per-recipient unacked-id list
|
||||
/// `acked_at = NOW`, then drain the list. On a sqlite error the list
|
||||
/// is kept so a retry acks the same rows. Fired by the harness after `TurnOutcome::Ok`.
|
||||
/// Returns the number of rows acked (zero is normal — claude
|
||||
/// may have not called recv during the turn). Tolerant of ids
|
||||
/// that no longer exist in the DB (vacuumed, manually deleted)
|
||||
|
|
@ -476,7 +477,7 @@ impl Broker {
|
|||
let mut inflight = self.inflight.lock().unwrap();
|
||||
let ids: Vec<i64> = inflight
|
||||
.get_mut(recipient)
|
||||
.map(|s| std::mem::take(&mut s.unacked_ids))
|
||||
.map(|s| s.unacked_ids.clone())
|
||||
.unwrap_or_default();
|
||||
if ids.is_empty() {
|
||||
return Ok(0);
|
||||
|
|
@ -497,6 +498,10 @@ impl Broker {
|
|||
params_vec.push(id);
|
||||
}
|
||||
let n = conn.execute(&sql, params_vec.as_slice())?;
|
||||
// Clear only after the UPDATE succeeded, so a failed ack can be retried.
|
||||
if let Some(s) = inflight.get_mut(recipient) {
|
||||
s.unacked_ids.clear();
|
||||
}
|
||||
Ok(u64::try_from(n).unwrap_or(0))
|
||||
}
|
||||
|
||||
|
|
@ -712,6 +717,27 @@ mod tests {
|
|||
assert!(pop_one(broker, "b").is_none());
|
||||
}
|
||||
|
||||
/// A failed UPDATE keeps the unacked ids: the retry acks the same rows.
|
||||
#[test]
|
||||
fn ack_turn_keeps_ids_when_update_fails() {
|
||||
let h = open_broker();
|
||||
let broker = &h.broker;
|
||||
broker.send(&msg("a", "b", "hi")).unwrap();
|
||||
pop_one(broker, "b").expect("popped");
|
||||
broker
|
||||
.conn
|
||||
.lock()
|
||||
.unwrap()
|
||||
.busy_timeout(std::time::Duration::ZERO)
|
||||
.unwrap();
|
||||
let blocker = rusqlite::Connection::open(&h.path).unwrap();
|
||||
blocker.execute_batch("BEGIN IMMEDIATE").unwrap();
|
||||
assert!(broker.ack_turn("b").is_err());
|
||||
blocker.execute_batch("ROLLBACK").unwrap();
|
||||
assert_eq!(broker.ack_turn("b").unwrap(), 1);
|
||||
assert_eq!(broker.ack_turn("b").unwrap(), 0);
|
||||
}
|
||||
|
||||
/// Bulk triage: three queued messages, agent acks up to the second
|
||||
/// id — the first two never deliver again, the third still pops.
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in a new issue