Avoid ack() race condition in JobQueueRedis
authorAaron Schulz <aschulz@wikimedia.org>
Wed, 20 Apr 2016 15:34:55 +0000 (08:34 -0700)
committerOri.livneh <ori@wikimedia.org>
Wed, 20 Apr 2016 16:35:30 +0000 (16:35 +0000)
The race would cause jobs to be be unclaimed but have
no actual job data, causing pop() to return false for
them.

Bug: T133089
Change-Id: Icc60388d4431ab7fa2ca2e46bbb0d212b2b94201

includes/jobqueue/JobQueueRedis.php

index d4a5334..990248a 100644 (file)
@@ -393,12 +393,17 @@ LUA;
                        static $script =
 <<<LUA
                        local kClaimed, kAttempts, kData = unpack(KEYS)
-                       local uuid = unpack(ARGV)
+                       local id = unpack(ARGV)
                        -- Unmark the job as claimed
-                       redis.call('zRem',kClaimed,uuid)
-                       redis.call('hDel',kAttempts,uuid)
+                       local removed = redis.call('zRem',kClaimed,id)
+                       -- Check if the job was recycled
+                       if removed == 0 then
+                               return 0
+                       end
+                       -- Delete the retry data
+                       redis.call('hDel',kAttempts,id)
                        -- Delete the job data itself
-                       return redis.call('hDel',kData,uuid)
+                       return redis.call('hDel',kData,id)
 LUA;
                        $res = $conn->luaEval( $script,
                                [