refactor: per-key TTL
This commit is contained in:
parent
0a85992331
commit
45d414fe29
1 changed files with 14 additions and 10 deletions
|
|
@ -3,6 +3,7 @@
|
|||
import pickle
|
||||
import re
|
||||
import time
|
||||
import typing
|
||||
from contextlib import suppress
|
||||
|
||||
import redis
|
||||
|
|
@ -406,12 +407,15 @@ class _TrackedConnection(redis.Connection):
|
|||
conn.read_response()
|
||||
|
||||
|
||||
_ClientCacheValue = tuple[typing.Any, int]
|
||||
|
||||
|
||||
class _ClientCache:
|
||||
def __init__(self, maxsize: int = 1024, ttl=10 * 60, monitor: RedisWrapper | None = None) -> None:
|
||||
self.monitor = frappe.cache
|
||||
self.monitor_id = self.monitor.client_id()
|
||||
self.maxsize = maxsize or 1024 # Expect 1024 * 4kb objects ~ 4MB
|
||||
self.ttl = ttl
|
||||
self.local_ttl = ttl
|
||||
self.expiration = time.monotonic() + ttl
|
||||
|
||||
self.redis: RedisWrapper = RedisWrapper.from_url(
|
||||
|
|
@ -423,18 +427,17 @@ class _ClientCache:
|
|||
if cint(protocol) == 3:
|
||||
frappe.throw("RESP3 is not supported while connecting to Redis.")
|
||||
self.invalidator_thread = self.run_invalidator_thread()
|
||||
self.local_cache = {}
|
||||
self.local_cache: dict[bytes, _ClientCacheValue] = {}
|
||||
self._conn_retries = 0
|
||||
|
||||
def get_value(self, key):
|
||||
key = self.redis.make_key(key)
|
||||
|
||||
if time.monotonic() > self.expiration:
|
||||
self.clear_cache()
|
||||
self.expiration = time.monotonic() + self.ttl
|
||||
|
||||
try:
|
||||
return self.local_cache[key]
|
||||
val = self.local_cache[key]
|
||||
if time.monotonic() < val[1]:
|
||||
return val[0]
|
||||
else:
|
||||
self.local_cache.pop(key, None) # expired
|
||||
except KeyError:
|
||||
pass # cache miss
|
||||
|
||||
|
|
@ -450,13 +453,14 @@ class _ClientCache:
|
|||
with suppress(RuntimeError):
|
||||
self.local_cache.pop(next(iter(self.local_cache)), None)
|
||||
|
||||
self.local_cache[key] = val
|
||||
self.local_cache[key] = (val, time.monotonic() + self.local_ttl)
|
||||
|
||||
return val
|
||||
|
||||
def set_value(self, key, val):
|
||||
key = self.redis.make_key(key)
|
||||
self.redis.set_value(key, val, shared=True)
|
||||
self.local_cache[key] = val
|
||||
self.local_cache[key] = (val, time.monotonic() + self.local_ttl)
|
||||
|
||||
def delete_value(self, key):
|
||||
key = self.redis.make_key(key)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue