mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 20:40:17 +02:00
Add locks to ensure process safety
This commit is contained in:
parent
1f55fbfccc
commit
20187cc73e
@ -3,11 +3,12 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from app_utils.allianceauth import get_redis_client
|
|
||||||
from redis import Redis, RedisError
|
from redis import Redis, RedisError
|
||||||
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
|
||||||
|
from allianceauth.utils.cache import get_redis_client
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ class ItemCounter:
|
|||||||
|
|
||||||
self._name = str(name)
|
self._name = str(name)
|
||||||
self._minimum = minimum
|
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
|
@property
|
||||||
def _cache_key(self) -> str:
|
def _cache_key(self) -> str:
|
||||||
@ -64,10 +65,11 @@ class ItemCounter:
|
|||||||
|
|
||||||
def reset(self, init_value: int = 0):
|
def reset(self, init_value: int = 0):
|
||||||
"""Reset counter to initial value."""
|
"""Reset counter to initial value."""
|
||||||
if self._minimum is not None and init_value < self._minimum:
|
with self._redis.lock(f"{self.CACHE_KEY_BASE}-reset"):
|
||||||
raise ValueError("Can not reset below minimum")
|
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):
|
def incr(self, delta: int = 1):
|
||||||
"""Increment counter by delta."""
|
"""Increment counter by delta."""
|
||||||
@ -78,19 +80,20 @@ class ItemCounter:
|
|||||||
|
|
||||||
def decr(self, delta: int = 1):
|
def decr(self, delta: int = 1):
|
||||||
"""Decrement counter by delta."""
|
"""Decrement counter by delta."""
|
||||||
if self._minimum is not None and self.value() == self._minimum:
|
with self._redis.lock(f"{self.CACHE_KEY_BASE}-decr"):
|
||||||
return
|
if self._minimum is not None and self.value() == self._minimum:
|
||||||
try:
|
return
|
||||||
cache.decr(self._cache_key, delta)
|
try:
|
||||||
except ValueError:
|
cache.decr(self._cache_key, delta)
|
||||||
pass
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
def value(self) -> Optional[int]:
|
def value(self) -> Optional[int]:
|
||||||
"""Return current value or None if not yet initialized."""
|
"""Return current value or None if not yet initialized."""
|
||||||
return cache.get(self._cache_key)
|
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."""
|
"""Return AA's default cache client or a stub if Redis is not available."""
|
||||||
redis = get_redis_client()
|
redis = get_redis_client()
|
||||||
try:
|
try:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user