local function lock_is_older_than (creation_timestamp_milliseconds, duration_milliseconds) if (creation_timestamp_milliseconds + duration_milliseconds < get_current_time_milliseconds()) then return true end return false end local function keep_alive_locks () local locks= redis.call("SMEMBERS", lock_owner_id) local extended= 0 local removed= 0 for _, member in ipairs(locks) do local lock= cjson.decode(member) if (lock_is_older_than(lock.creation_time_milliseconds, max_lock_lifetime_seconds*1000)) then errorLog("The lock with key '%s' (owned by '%s') was found to exist longer than %s seconds and its lifetime will not be extended. " .. "This is an indicator of a logic failure! Please report this issue.", lock.lock_key, lock_owner_id, max_lock_lifetime_seconds) remove_from_current_lock_owner_set(member) removed = removed + 1 else -- extend lock's expiration local result = redis.call("EXPIRE", lock.lock_key, default_lock_lifetime_seconds) if (result == 1) then local warnThresholdSeconds= math.floor(default_lock_lifetime_seconds / 2) if (lock_is_older_than(lock.creation_time_milliseconds, warnThresholdSeconds*1000)) then warnLog("The lock with key '%s' (owned by '%s') was found to exist longer than %s seconds. " .. "This is an indicator of slow requests.", lock.lock_key, lock_owner_id, warnThresholdSeconds) end extended = extended + 1 else -- remove lock entry from set as it no longer exists remove_from_current_lock_owner_set(member) removed = removed + 1 end end end if (extended > 0 or removed > 0) then debugLog("Iteration through set of size %d for lock owner '%s' extended expiration of %d locks and removed %d entries.", #locks, lock_owner_id, extended, removed) end -- make sure an unused set is deleted after 'max_lock_lifetime_seconds' redis.call("EXPIRE", lock_owner_id, max_lock_lifetime_seconds) return { "ok" } end return scriptResult(keep_alive_locks())