Use MAX_LOCK_TTL in RedisLockManager to avoid premature lock expiration
authorAaron Schulz <aschulz@wikimedia.org>
Fri, 30 Sep 2016 13:36:35 +0000 (06:36 -0700)
committerAaron Schulz <aschulz@wikimedia.org>
Fri, 30 Sep 2016 13:36:41 +0000 (06:36 -0700)
App servers should not lower the redis structure TTL of locks set
from CLI scripts, which is what would typically happen before if
they touched the same keys. Instead, keep a high lock record TTL
and rely on the logical TTLs for expiry semantics.

Change-Id: I2948369845c47d2682a85dd0564673f3b813be83

includes/libs/lockmanager/RedisLockManager.php

index 6001705..ea9dde7 100644 (file)
@@ -102,7 +102,7 @@ class RedisLockManager extends QuorumLockManager {
 <<<LUA
                        local failed = {}
                        -- Load input params (e.g. session, ttl, time of request)
-                       local rSession, rTTL, rTime = unpack(ARGV)
+                       local rSession, rTTL, rMaxTTL, rTime = unpack(ARGV)
                        -- Check that all the locks can be acquired
                        for i,requestKey in ipairs(KEYS) do
                                local _, _, rType, resourceKey = string.find(requestKey,"(%w+):(%w+)$")
@@ -133,7 +133,7 @@ class RedisLockManager extends QuorumLockManager {
                                        local _, _, rType, resourceKey = string.find(requestKey,"(%w+):(%w+)$")
                                        redis.call('hSet',resourceKey,rType .. ':' .. rSession,rTime + rTTL)
                                        -- In addition to invalidation logic, be sure to garbage collect
-                                       redis.call('expire',resourceKey,rTTL)
+                                       redis.call('expire',resourceKey,rMaxTTL)
                                end
                        end
                        return failed
@@ -144,7 +144,8 @@ LUA;
                                        [
                                                $this->session, // ARGV[1]
                                                $this->lockTTL, // ARGV[2]
-                                               time() // ARGV[3]
+                                               self::MAX_LOCK_TTL, // ARGV[3]
+                                               time() // ARGV[4]
                                        ]
                                ),
                                count( $pathsByKey ) # number of first argument(s) that are keys