ForcePilot/backend/package/yuxi/channel/extensions/jira/loopbreaker.py

43 lines
1.3 KiB
Python
Raw Normal View History

from __future__ import annotations
import logging
import time
from collections import defaultdict
logger = logging.getLogger(__name__)
class JiraLoopBreaker:
def __init__(self, max_comments_per_issue_per_minute: int = 8):
self._counters: dict[str, list[float]] = defaultdict(list)
self._max = max_comments_per_issue_per_minute
self._tripped: dict[str, float] = {}
def record_and_check(self, issue_key: str) -> bool:
now = time.monotonic()
window = [t for t in self._counters.get(issue_key, []) if now - t < 60]
if len(window) >= self._max:
self._tripped[issue_key] = now
logger.warning(
"Jira loop breaker tripped for issue=%s, comments=%d",
issue_key,
len(window),
)
return False
window.append(now)
self._counters[issue_key] = window
return True
def is_tripped(self, issue_key: str) -> bool:
now = time.monotonic()
trip_time = self._tripped.get(issue_key)
if trip_time and now - trip_time < 300:
return True
if trip_time and now - trip_time >= 300:
del self._tripped[issue_key]
return False
def reset_issue(self, issue_key: str):
self._counters.pop(issue_key, None)
self._tripped.pop(issue_key, None)