From 7df705691db6ae8d4e5f0615a7d3544533407caf Mon Sep 17 00:00:00 2001 From: Judah Rand <17158624+judahrand@users.noreply.github.com> Date: Thu, 6 Oct 2022 12:14:06 +0100 Subject: [PATCH] Use `ARGV` for Redis lua scripts Closes #31 --- CHANGELOG.rst | 2 ++ sherlock/lock.py | 24 ++++++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9ed03e7..cf1b385 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,9 +14,11 @@ Development Version * [FEAT] Install backend specific dependencies with extras #59_ * [FEAT] Add `.renew()` method to all backends #61_ +* [BUGFIX] Use `ARGV` in Redis Lua scripts to add RedisCluster compatibility #31_ * [BUGFIX] `redis>=2.10.6` client won't work with `sherlock 0.3.1` #32_ * [BUGFIX] `timeout=0` doesn't work as expected with `RedisLock` #60_ +.. _#31: https://github.com/vaidik/sherlock/issues/31 .. _#32: https://github.com/vaidik/sherlock/issues/32 .. _#59: https://github.com/py-sherlock/sherlock/pull/59 .. _#60: https://github.com/py-sherlock/sherlock/pull/60 diff --git a/sherlock/lock.py b/sherlock/lock.py index 7e1063f..ffad942 100644 --- a/sherlock/lock.py +++ b/sherlock/lock.py @@ -412,16 +412,16 @@ class RedisLock(BaseLock): """ _acquire_script = """ - local result = redis.call('SETNX', KEYS[1], KEYS[2]) - if result == 1 and KEYS[3] ~= -1 then - redis.call('EXPIRE', KEYS[1], KEYS[3]) + local result = redis.call('SETNX', KEYS[1], ARGV[1]) + if result == 1 and ARGV[2] ~= -1 then + redis.call('EXPIRE', KEYS[1], ARGV[2]) end return result """ _release_script = """ local result = 0 - if redis.call('GET', KEYS[1]) == KEYS[2] then + if redis.call('GET', KEYS[1]) == ARGV[1] then redis.call('DEL', KEYS[1]) result = 1 end @@ -430,9 +430,9 @@ class RedisLock(BaseLock): _renew_script = """ local result = 0 - if redis.call('GET', KEYS[1]) == KEYS[2] then - if KEYS[3] ~= -1 then - redis.call('EXPIRE', KEYS[1], KEYS[3]) + if redis.call('GET', KEYS[1]) == ARGV[1] then + if ARGV[2] ~= -1 then + redis.call('EXPIRE', KEYS[1], ARGV[2]) else redis.call('PERSIST', KEYS[1]) end @@ -485,7 +485,7 @@ def _acquire(self): expire = -1 else: expire = self.expire - if self._acquire_func(keys=[self._key_name, owner, expire]) != 1: + if self._acquire_func(keys=[self._key_name], args=[owner, expire]) != 1: return False self._owner = owner return True @@ -494,7 +494,7 @@ def _release(self): if self._owner is None: raise LockException("Lock was not set by this process.") - if self._release_func(keys=[self._key_name, self._owner]) != 1: + if self._release_func(keys=[self._key_name], args=[self._owner]) != 1: raise LockException( "Lock could not be released because it was " "not acquired by this instance." @@ -506,7 +506,10 @@ def _renew(self) -> bool: if self._owner is None: raise LockException("Lock was not set by this process.") - if self._release_func(keys=[self._key_name, self._owner, self.expire]) != 1: + if ( + self._release_func(keys=[self._key_name], args=[self._owner, self.expire]) + != 1 + ): return False return True @@ -1209,6 +1212,7 @@ def _release(self) -> None: if self._owner == data["owner"]: self._data_file.unlink() + pathlib.Path(self._lock_file.lock_file).unlink() def _renew(self) -> bool: if self._owner is None: