diff options
Diffstat (limited to 'shared/src')
| -rw-r--r-- | shared/src/shared/resilience.py | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/shared/src/shared/resilience.py b/shared/src/shared/resilience.py index b18aaf7..ef2a1f6 100644 --- a/shared/src/shared/resilience.py +++ b/shared/src/shared/resilience.py @@ -12,8 +12,15 @@ import logging import random import time from contextlib import asynccontextmanager +from enum import StrEnum from typing import Any, Callable + +class _State(StrEnum): + CLOSED = "closed" + OPEN = "open" + HALF_OPEN = "half_open" + logger = logging.getLogger(__name__) @@ -73,17 +80,17 @@ class CircuitBreaker: """ def __init__(self, failure_threshold: int = 5, cooldown: float = 60.0) -> None: - self.failure_threshold = failure_threshold - self.cooldown = cooldown + self._failure_threshold = failure_threshold + self._cooldown = cooldown self._failures = 0 - self._state = "closed" + self._state = _State.CLOSED self._opened_at: float = 0.0 async def call(self, func: Callable, *args: Any, **kwargs: Any) -> Any: """Execute func through the breaker.""" - if self._state == "open": - if time.monotonic() - self._opened_at >= self.cooldown: - self._state = "half_open" + if self._state == _State.OPEN: + if time.monotonic() - self._opened_at >= self._cooldown: + self._state = _State.HALF_OPEN else: raise RuntimeError("Circuit breaker is open") @@ -91,15 +98,15 @@ class CircuitBreaker: result = await func(*args, **kwargs) except Exception: self._failures += 1 - if self._state == "half_open": - self._state = "open" + if self._state == _State.HALF_OPEN: + self._state = _State.OPEN self._opened_at = time.monotonic() logger.error( "Circuit breaker re-opened after half-open probe failure (threshold=%d)", - self.failure_threshold, + self._failure_threshold, ) - elif self._failures >= self.failure_threshold: - self._state = "open" + elif self._failures >= self._failure_threshold: + self._state = _State.OPEN self._opened_at = time.monotonic() logger.error( "Circuit breaker opened after %d consecutive failures", @@ -109,7 +116,7 @@ class CircuitBreaker: # Success: reset self._failures = 0 - self._state = "closed" + self._state = _State.CLOSED return result |
