Skip to content

Commit

Permalink
changed incr and decr's internal method to use python methods instead…
Browse files Browse the repository at this point in the history
… of lua scripts
  • Loading branch information
amirreza8002 committed Dec 19, 2024
1 parent c295f5f commit 109da5a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 80 deletions.
78 changes: 39 additions & 39 deletions django_valkey/async_cache/client/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,50 +533,41 @@ async def mset(
async def _incr(
self,
key,
delta: int = 1,
amount: int = 1,
version: int | None = None,
client: AValkey | Any | None = None,
ignoree_key_check: bool = False,
) -> int:
ignore_key_check: bool = False,
client: AValkey | None = None,
_operation="incr",
):
client = await self._get_client(write=True, client=client)
op = client.incrby if _operation == "incr" else client.decrby
key = await self.make_key(key, version=version)

try:
try:
# if key expired after exists check, then we get
# key with wrong value and ttl -1.
# use lua script for atomicity
if not ignoree_key_check:
lua = """
local exists = server.call('EXISTS', KEYS[1])
if (exists == 1) then
return server.call('INCRBY', KEYS[1], ARGV[1])
else return false end
"""
if ignore_key_check:
value = await op(key, amount)
else:
if await client.exists(key):
value = await op(key, amount)
else:
lua = """
return server.call('INCRBY', KEYS[1], ARGV[1])
"""
value = await client.eval(lua, 1, key, delta)
if value is None:
error_message = f"Key '{key!r}' not found"
raise ValueError(error_message)
except ResponseError as e:
# if cached value or total value is greater than 64-bit signed
# integer.
# elif int is encoded. so valkey sees the data as string.
# In these situations valkey will throw ResponseError

# try to keep TTL of key
timeout = await self.ttl(key, version=version, client=client)

if timeout == -2:
error_message = f"Key '{key!r}' not found"
raise ValueError(error_message) from e
value = await self.get(key, version=version, client=client) + delta
await self.set(
key, value, version=version, timeout=timeout, client=client
)
except ResponseError as e:
# if cached value or total value is greater than 64-bit signed
# integer.
# elif int is encoded. so valkey sees the data as string.
# In these situations valkey will throw ResponseError

# try to keep TTL of key
timeout = await self.ttl(key, version=version, client=client)

if timeout == -2:
error_message = f"Key '{key!r}' not found"
raise ValueError(error_message) from e
if _operation == "incr":
value = await self.get(key, version=version, client=client) + amount
else:
value = await self.get(key, version=version, client=client) - amount
await self.set(key, value, version=version, timeout=timeout, client=client)
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e

Expand All @@ -600,7 +591,8 @@ async def incr(
delta,
version=version,
client=client,
ignoree_key_check=ignore_key_check,
ignore_key_check=ignore_key_check,
_operation="incr",
)

aincr = incr
Expand All @@ -611,12 +603,20 @@ async def decr(
delta: int = 1,
version: int | None = None,
client: AValkey | Any | None = None,
ignore_key_check: bool = False,
) -> int:
"""
Decrease delta to value in the cache. If the key does not exist, raise a
ValueError exception.
"""
return await self._incr(key, delta=-delta, version=version, client=client)
return await self._incr(
key,
amount=delta,
version=version,
client=client,
ignore_key_check=ignore_key_check,
_operation="decr",
)

adecr = decr

Expand Down
76 changes: 35 additions & 41 deletions django_valkey/base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,55 +667,46 @@ def mset(

def _incr(
self,
key: KeyT,
delta: int = 1,
key,
amount: int = 1,
version: int | None = None,
client: Backend | Any | None = None,
ignore_key_check: bool = False,
) -> int:
client: Backend | None = None,
_operation="incr",
):
client = self._get_client(write=True, client=client)

op = client.incrby if _operation == "incr" else client.decrby
key = self.make_key(key, version=version)

try:
try:
# if key expired after exists check, then we get
# key with wrong value and ttl -1.
# use lua script for atomicity
if not ignore_key_check:
lua = """
local exists = server.call('EXISTS', KEYS[1])
if (exists == 1) then
return server.call('INCRBY', KEYS[1], ARGV[1])
else return false end
"""
if ignore_key_check:
value = op(key, amount)
else:
if client.exists(key):
value = op(key, amount)
else:
lua = """
return server.call('INCRBY', KEYS[1], ARGV[1])
"""
value = client.eval(lua, 1, key, delta)
if value is None:
error_message = f"Key '{key!r}' not found"
raise ValueError(error_message)
except ResponseError as e:
# if cached value or total value is greater than 64-bit signed
# integer.
# elif int is encoded. so valkey sees the data as string.
# In these situations valkey will throw ResponseError

# try to keep TTL of key
timeout = self.ttl(key, version=version, client=client)

# returns -2 if the key does not exist
# means, that key have expired
if timeout == -2:
error_message = f"Key '{key!r}' not found"
raise ValueError(error_message) from e
value = self.get(key, version=version, client=client) + delta
self.set(key, value, version=version, timeout=timeout, client=client)
except ResponseError as e:
# if cached value or total value is greater than 64-bit signed
# integer.
# elif int is encoded. so valkey sees the data as string.
# In these situations valkey will throw ResponseError

# try to keep TTL of key
timeout = self.ttl(key, version=version, client=client)

# returns -2 if the key does not exist
# means, that key have expired
if timeout == -2:
error_message = f"Key '{key!r}' not found"
raise ValueError(error_message) from e
if _operation == "incr":
value = self.get(key, version=version, client=client) + amount
else:
value = self.get(key, version=version, client=client) - amount
self.set(key, value, version=version, timeout=timeout, client=client)
except _main_exceptions as e:
raise ConnectionInterrupted(connection=client) from e

return value

def incr(
Expand All @@ -733,10 +724,11 @@ def incr(
"""
return self._incr(
key=key,
delta=delta,
amount=delta,
version=version,
client=client,
ignore_key_check=ignore_key_check,
_operation="incr",
)

def decr(
Expand All @@ -750,7 +742,9 @@ def decr(
Decrease delta to value in the cache. If the key does not exist, raise a
ValueError exception.
"""
return self._incr(key=key, delta=-delta, version=version, client=client)
return self._incr(
key=key, amount=delta, version=version, client=client, _operation="decr"
)

def ttl(
self, key: KeyT, version: int | None = None, client: Backend | Any | None = None
Expand Down

0 comments on commit 109da5a

Please sign in to comment.