From 482952fa3cf09d1fe68d727bfae779020d577d0d Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Fri, 25 Sep 2026 13:35:42 +0000 Subject: [PATCH] fix(queue): lease messages with FOR UPDATE SKIP LOCKED so two readers never share one Queue.read() selected the visible candidates and then bumped their vt in a second statement. On libSQL the single multiplexed connection and the in-process write lock serialised readers, so that was safe; on the Postgres pool (#239) two concurrent readers see the same candidates and both lease them. The integration test 'never hands the same message to two readers' failed against a real Postgres (36 leases of 10 messages). The select now locks the rows it is about to lease and skips rows another reader holds. Co-Authored-By: Claude Fable 5.1 --- packages/shared/lib/queue.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/shared/lib/queue.js b/packages/shared/lib/queue.js index 3f99263..ce7d8d7 100644 --- a/packages/shared/lib/queue.js +++ b/packages/shared/lib/queue.js @@ -78,7 +78,8 @@ export class Queue { from queue_messages where queue_name = ? and vt <= ? order by msg_id - limit ?`, + limit ? + for update skip locked`, [this.name, nowIso, qty], );