Advanced Usage
Custom Exception Handling
You can customize which exceptions should be considered failures:
def should_consider_failure(exception):
# Only count network errors as failures
return isinstance(exception, (ConnectionError, TimeoutError, requests.ConnectionError))
circuit_breaker = CircuitProtectorPolicy(
resource_key="my_service",
should_handle=should_consider_failure
)
@circuit_breaker
def my_function():
# Only ConnectionError and TimeoutError will count as failures
pass
Monitoring and Status Changes
You can monitor circuit breaker status changes:
def on_status_change(policy, old_status, new_status):
print(f"Circuit breaker {policy.resource_key} changed from {old_status.name} to {new_status.name}")
circuit_breaker = CircuitProtectorPolicy(
resource_key="my_service",
on_status_change=on_status_change
)
Accessing Circuit Breaker State
You can access the current status and execution log:
circuit_breaker = CircuitProtectorPolicy(resource_key="my_service")
# Check current status
print(f"Current status: {circuit_breaker.status.name}")
# Check execution log
print(f"Execution log: {list(circuit_breaker.execution_log)}")
# The execution_log buffer maintains success/failure record
if circuit_breaker.status == CircuitState.OPEN:
print("Circuit breaker is currently open - requests are blocked")
else:
# Execute call if not in OPEN status
pass
Performance Considerations
When using PostgreSQL storage, consider these performance tips:
The library uses row-level locking (
FOR UPDATE) for atomic operationsProper indexing ensures fast lookups and updates
The
updated_attrigger only fires when values actually changeConnection pooling is recommended for high-throughput applications