From 5a4d22cc6d6542839097f4c821e4e29f5e9b4c95 Mon Sep 17 00:00:00 2001 From: Gianluca Zuccarelli Date: Tue, 13 Sep 2022 13:52:26 +0100 Subject: [PATCH] pkg/dbjobqueue: fix enqueue/dequeue race condition Currently there is a race condition that occurs between the dbjobqueue enqueue and dequeue functions. Both queries make use of the postgres `now()` timestamp function which returns the timestamp of when the transaction started and not when the statement is executed. The result of this is a timestamp for a job's `started_at` field to be earlier than its `queued_at` field causing a constraint violation. Since the dequeue query will never be executed before the enqueue query, changing the postgres timestamp function to `statement_timestamp()` resolves this issue. --- pkg/jobqueue/dbjobqueue/dbjobqueue.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/jobqueue/dbjobqueue/dbjobqueue.go b/pkg/jobqueue/dbjobqueue/dbjobqueue.go index 970c41a4c..8b54a1a9b 100644 --- a/pkg/jobqueue/dbjobqueue/dbjobqueue.go +++ b/pkg/jobqueue/dbjobqueue/dbjobqueue.go @@ -28,10 +28,10 @@ const ( sqlListen = `LISTEN jobs` sqlUnlisten = `UNLISTEN jobs` - sqlEnqueue = `INSERT INTO jobs(id, type, args, queued_at, channel) VALUES ($1, $2, $3, NOW(), $4)` + sqlEnqueue = `INSERT INTO jobs(id, type, args, queued_at, channel) VALUES ($1, $2, $3, statement_timestamp(), $4)` sqlDequeue = ` UPDATE jobs - SET token = $1, started_at = now() + SET token = $1, started_at = statement_timestamp() WHERE id = ( SELECT id FROM ready_jobs @@ -45,7 +45,7 @@ const ( sqlDequeueByID = ` UPDATE jobs - SET token = $1, started_at = now() + SET token = $1, started_at = statement_timestamp() WHERE id = ( SELECT id FROM ready_jobs