更改项目名为NebulaShell
This commit is contained in:
64
store/@{NebulaShell}/plugin-loader-pro/circuit/breaker.py
Normal file
64
store/@{NebulaShell}/plugin-loader-pro/circuit/breaker.py
Normal file
@@ -0,0 +1,64 @@
|
||||
"""熔断器实现"""
|
||||
import time
|
||||
from typing import Callable, Any
|
||||
from .state import CircuitState
|
||||
|
||||
|
||||
class CircuitBreaker:
|
||||
"""熔断器"""
|
||||
|
||||
def __init__(self, failure_threshold: int = 3, recovery_timeout: int = 60, half_open_requests: int = 1):
|
||||
self.failure_threshold = failure_threshold
|
||||
self.recovery_timeout = recovery_timeout
|
||||
self.half_open_requests = half_open_requests
|
||||
|
||||
self.state = CircuitState.CLOSED
|
||||
self.failure_count = 0
|
||||
self.success_count = 0
|
||||
self.last_failure_time = 0
|
||||
self.half_open_calls = 0
|
||||
|
||||
def call(self, func: Callable, *args, **kwargs) -> Any:
|
||||
"""执行调用"""
|
||||
if self.state == CircuitState.OPEN:
|
||||
if time.time() - self.last_failure_time >= self.recovery_timeout:
|
||||
self.state = CircuitState.HALF_OPEN
|
||||
self.half_open_calls = 0
|
||||
else:
|
||||
raise Exception("熔断器已打开,调用被拒绝")
|
||||
|
||||
try:
|
||||
result = func(*args, **kwargs)
|
||||
self._on_success()
|
||||
return result
|
||||
except Exception as e:
|
||||
self._on_failure()
|
||||
raise
|
||||
|
||||
def _on_success(self):
|
||||
"""成功回调"""
|
||||
self.failure_count = 0
|
||||
if self.state == CircuitState.HALF_OPEN:
|
||||
self.half_open_calls += 1
|
||||
if self.half_open_calls >= self.half_open_requests:
|
||||
self.state = CircuitState.CLOSED
|
||||
self.half_open_calls = 0
|
||||
|
||||
def _on_failure(self):
|
||||
"""失败回调"""
|
||||
self.failure_count += 1
|
||||
self.last_failure_time = time.time()
|
||||
|
||||
if self.state == CircuitState.HALF_OPEN:
|
||||
self.state = CircuitState.OPEN
|
||||
elif self.failure_count >= self.failure_threshold:
|
||||
self.state = CircuitState.OPEN
|
||||
|
||||
def reset(self):
|
||||
"""重置熔断器"""
|
||||
self.state = CircuitState.CLOSED
|
||||
self.failure_count = 0
|
||||
self.half_open_calls = 0
|
||||
|
||||
def get_state(self) -> str:
|
||||
return self.state
|
||||
Reference in New Issue
Block a user