local function acquire_lock (key, lock_id, lock_lifetime_milliseconds) if is_locked_by_another_owner(key, lock_id) then return { "locked_by_other" } end if owns_lock(key, lock_id) then debugLog("lock is already owned for key '%s' and lock ID '%s'", key, lock_id) return { "ok" } end local existing_lock = redis.call("SET", lock_key(key), lock_id, "NX", "PX", lock_lifetime_milliseconds, "GET") if existing_lock then errorLog("key '%s' was not expected to be locked but was locked by lock ID '%s'", key, existing_lock) else store_lock_for_owner(lock_key(key)) debugLog("successfully acquired new lock for key '%s' and lock ID '%s'", key, lock_id) end return { "ok" } end local function acquire_locks (keys, lock_id, lock_lifetime_milliseconds) for _, key in ipairs(keys) do acquire_lock(key, lock_id, lock_lifetime_milliseconds) end end local function release_lock (key, lock_id) local existing_lock_id = get_existing_lock(key) if existing_lock_id == lock_id then redis.call("DEL", lock_key(key)) release_lock_for_owner(lock_key(key)) debugLog("successfully released lock for key '%s' and lock ID '%s'", key, lock_id) return { "ok" } end debugLog("could not release lock for key '%s' and lock ID '%s' because lock ID did not match", key, lock_id) return { "lock_not_owned", existing_lock_id } end local function release_locks (keys, lock_id) for _, key in ipairs(keys) do release_lock(key, lock_id) end end