Commit 8ad4021d authored by Vitaly Lipatov's avatar Vitaly Lipatov

gateway: serialize concurrent autoban updates

parent fbb077d7
...@@ -14,6 +14,7 @@ AutoBanManager - управление автоматической разбло ...@@ -14,6 +14,7 @@ AutoBanManager - управление автоматической разбло
import time import time
import logging import logging
from redis.exceptions import WatchError
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -73,13 +74,14 @@ class AutoBanManager: ...@@ -73,13 +74,14 @@ class AutoBanManager:
if not self.enabled: if not self.enabled:
return None return None
try:
meta_key = f"{self.META_PREFIX}{ip}" meta_key = f"{self.META_PREFIX}{ip}"
for _ in range(3):
pipeline = self.r.pipeline()
try:
pipeline.watch(meta_key, self.PERMANENT_KEY)
now = int(time.time()) now = int(time.time())
existing = pipeline.hgetall(meta_key)
# Получаем существующие метаданные is_permanent = pipeline.sismember(self.PERMANENT_KEY, ip)
existing = self.r.hgetall(meta_key)
is_permanent = self.r.sismember(self.PERMANENT_KEY, ip)
if existing: if existing:
offense_count = int(existing.get(b'offense_count', 0)) offense_count = int(existing.get(b'offense_count', 0))
...@@ -108,7 +110,7 @@ class AutoBanManager: ...@@ -108,7 +110,7 @@ class AutoBanManager:
'source': source, 'source': source,
'reason': reason 'reason': reason
} }
pipeline = self.r.pipeline(transaction=True) pipeline.multi()
pipeline.hset(meta_key, mapping=metadata) pipeline.hset(meta_key, mapping=metadata)
# Добавляем в расписание авто-разбана или в постоянные # Добавляем в расписание авто-разбана или в постоянные
...@@ -127,9 +129,15 @@ class AutoBanManager: ...@@ -127,9 +129,15 @@ class AutoBanManager:
return metadata return metadata
except WatchError:
continue
except Exception as e: except Exception as e:
log.error(f"AutoBanManager.on_ban error: {e}") log.error(f"AutoBanManager.on_ban error: {e}")
return None return None
finally:
pipeline.reset()
log.error("AutoBanManager.on_ban conflict retries exhausted")
return None
def on_unban(self, ip, reset_counter=False): def on_unban(self, ip, reset_counter=False):
""" """
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment