Add locks to ensure process safety

This commit is contained in:
ErikKalkoken 2023-08-02 15:58:36 +02:00
parent 1f55fbfccc
commit 20187cc73e

View File

@ -3,11 +3,12 @@
import logging
from typing import Optional
from app_utils.allianceauth import get_redis_client
from redis import Redis, RedisError
from django.core.cache import cache
from allianceauth.utils.cache import get_redis_client
logger = logging.getLogger(__name__)
@ -56,7 +57,7 @@ class ItemCounter:
self._name = str(name)
self._minimum = minimum
self._redis = redis if redis else get_redis_client()
self._redis = get_redis_client_or_stub() if not redis else redis
@property
def _cache_key(self) -> str:
@ -64,10 +65,11 @@ class ItemCounter:
def reset(self, init_value: int = 0):
"""Reset counter to initial value."""
if self._minimum is not None and init_value < self._minimum:
raise ValueError("Can not reset below minimum")
with self._redis.lock(f"{self.CACHE_KEY_BASE}-reset"):
if self._minimum is not None and init_value < self._minimum:
raise ValueError("Can not reset below minimum")
cache.set(self._cache_key, init_value, self.DEFAULT_CACHE_TIMEOUT)
cache.set(self._cache_key, init_value, self.DEFAULT_CACHE_TIMEOUT)
def incr(self, delta: int = 1):
"""Increment counter by delta."""
@ -78,19 +80,20 @@ class ItemCounter:
def decr(self, delta: int = 1):
"""Decrement counter by delta."""
if self._minimum is not None and self.value() == self._minimum:
return
try:
cache.decr(self._cache_key, delta)
except ValueError:
pass
with self._redis.lock(f"{self.CACHE_KEY_BASE}-decr"):
if self._minimum is not None and self.value() == self._minimum:
return
try:
cache.decr(self._cache_key, delta)
except ValueError:
pass
def value(self) -> Optional[int]:
"""Return current value or None if not yet initialized."""
return cache.get(self._cache_key)
def get_redis_client_or_stub():
def get_redis_client_or_stub() -> Redis:
"""Return AA's default cache client or a stub if Redis is not available."""
redis = get_redis_client()
try: