Replies: 5 comments 4 replies
|
There is a |
|
Seems found a relevant bug report, related to this issue: #16043 |
|
I would not call The linked #16043 is the important bit: current job claiming is not a safe multi-runner claim for the same queue yet, and the source comment says it sets
|
|
I see a PR #17441 that is trying to fix this issue - awesome! |
|
The real fix here doesn't depend on Payload's internal job claiming at all: treat the notification send itself as the idempotency boundary, not the job dequeue. Add a dedupe table (or a Redis key if you already have Redis) keyed on whatever uniquely identifies "this notification, once" — something like Before sending, try to insert that key with a unique constraint (Postgres/Mongo unique index) or This sidesteps the queue's internal claiming race entirely, because it doesn't matter how many times the job runs or how many workers pick it up concurrently — the side effect itself can only fire once per key. It's also worth doing even after #17441 lands, since that PR hardens job claiming at the queue level, but any at-least-once queue can still redeliver a job after a worker crashes mid-execution but after the side effect already ran. Idempotency at the point of the actual external effect is the only thing that's airtight against that class of failure — the queue-level fix reduces how often you'll need the fallback, but doesn't remove the need for it. Concretely for a notification send: const dedupeKey = `${docId}:${userId}:${event}`
const claimed = await tryClaim(taskSlug, dedupeKey) // unique insert or Redis SETNX with TTL
if (!claimed) return // already sent, no-op
await sendNotification(...)Set a TTL/expiry on the dedupe record that's comfortably longer than your job's max retry window, so it doesn't grow unbounded but still covers realistic redelivery windows. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I have jobs that send notifications on doc update to multiple users (actually, PUSH, but let's be email, as in the example) on the afterChange hook, here is the code:
It works great, but sometimes users receive the same notifications multiple times! This seem happens when several documents updated simultaneously, and the
run()from the second afterChange hook also takes into work tasks from the first afterChange hook, as they are not finished yet.So, seems Payload jobs runner doesn't lock the jobs, taken from the queue, right?
And the question is how to prevent this issue and enable locking of jobs, to prevent multiple execution of them?
All reactions