0
# Core Circuit Breaker
1
2
The main `CircuitBreaker` class provides the core functionality for implementing the Circuit Breaker pattern. It monitors function calls, tracks failures, and manages state transitions to prevent cascading failures in distributed systems.
3
4
## Capabilities
5
6
### Circuit Breaker Creation
7
8
Creates a new circuit breaker instance with configurable parameters for failure thresholds, timeouts, and behavior customization.
9
10
```python { .api }
11
class CircuitBreaker:
12
def __init__(self,
13
fail_max: int = 5,
14
reset_timeout: float = 60,
15
success_threshold: int = 1,
16
exclude: Iterable[type | Callable[[Any], bool]] | None = None,
17
listeners: Sequence[CircuitBreakerListener] | None = None,
18
state_storage: CircuitBreakerStorage | None = None,
19
name: str | None = None,
20
throw_new_error_on_trip: bool = True):
21
"""
22
Create a new circuit breaker with the given parameters.
23
24
Args:
25
fail_max (int): Maximum consecutive failures before opening circuit
26
reset_timeout (float): Timeout in seconds before allowing trial calls
27
success_threshold (int): Successful calls needed to close from half-open
28
exclude (Iterable[type | Callable[[Any], bool]] | None): Exception types/callables to exclude from failure counting
29
listeners (Sequence[CircuitBreakerListener] | None): Event listeners to register
30
state_storage (CircuitBreakerStorage | None): Storage backend for circuit state (defaults to memory)
31
name (str | None): Optional name for circuit breaker identification
32
throw_new_error_on_trip (bool): Whether to throw CircuitBreakerError on trip
33
"""
34
```
35
36
### Function Protection
37
38
Protects function calls with circuit breaker logic, supporting multiple invocation patterns including decorator, direct call, and context manager usage.
39
40
```python { .api }
41
def call(self, func, *args, **kwargs):
42
"""
43
Call func with the given args and kwargs according to circuit breaker rules.
44
45
Args:
46
func: The function to call
47
*args: Positional arguments for the function
48
**kwargs: Keyword arguments for the function
49
50
Returns:
51
The return value of the function call
52
53
Raises:
54
CircuitBreakerError: When circuit is open (if throw_new_error_on_trip=True)
55
Original exception: When function fails and circuit doesn't trip
56
"""
57
58
def calling(self):
59
"""
60
Return a context manager for use with 'with' statements.
61
62
Returns:
63
Context manager that executes code block under circuit breaker protection
64
"""
65
66
def __call__(self, *call_args: Any, **call_kwargs: bool) -> Callable:
67
"""
68
Return a decorator that protects the decorated function.
69
70
Args:
71
*call_args: Function to decorate (when used as @decorator)
72
**call_kwargs: Keyword arguments including __pybreaker_call_async for async support
73
74
Returns:
75
Decorator function that applies circuit breaker protection
76
"""
77
```
78
79
### State Management
80
81
Manual control over circuit breaker state, allowing operations teams to manage circuit states during maintenance or troubleshooting.
82
83
```python { .api }
84
def open(self) -> bool:
85
"""
86
Manually open the circuit breaker.
87
88
Returns:
89
bool: Value of throw_new_error_on_trip setting
90
"""
91
92
def close(self) -> None:
93
"""
94
Manually close the circuit breaker.
95
Resets failure counter and success counter.
96
"""
97
98
def half_open(self) -> None:
99
"""
100
Manually set circuit breaker to half-open state.
101
Allows one trial call to test if circuit should close.
102
"""
103
```
104
105
### Properties and Monitoring
106
107
Access to circuit breaker state and configuration for monitoring and management purposes.
108
109
```python { .api }
110
@property
111
def fail_counter(self) -> int:
112
"""Current number of consecutive failures."""
113
114
@property
115
def success_counter(self) -> int:
116
"""Current number of consecutive successes in half-open state."""
117
118
@property
119
def fail_max(self) -> int:
120
"""Maximum number of failures before opening circuit."""
121
122
@fail_max.setter
123
def fail_max(self, number: int) -> None:
124
"""Set the maximum number of failures before opening circuit."""
125
126
@property
127
def reset_timeout(self) -> float:
128
"""Timeout period in seconds before allowing trial calls."""
129
130
@reset_timeout.setter
131
def reset_timeout(self, timeout: float) -> None:
132
"""Set the timeout period in seconds."""
133
134
@property
135
def success_threshold(self) -> int:
136
"""Number of successful requests required before closing from half-open."""
137
138
@success_threshold.setter
139
def success_threshold(self, threshold: int) -> None:
140
"""Set the success threshold for closing from half-open state."""
141
142
@property
143
def state(self):
144
"""Update (if needed) and return the cached state object."""
145
146
@state.setter
147
def state(self, state_str: str) -> None:
148
"""Set cached state and notify listeners of newly cached state."""
149
150
@property
151
def current_state(self) -> str:
152
"""Current state of the circuit breaker ('open', 'closed', 'half-open')."""
153
154
@property
155
def name(self) -> str:
156
"""Name of this circuit breaker for identification."""
157
158
@name.setter
159
def name(self, name: str) -> None:
160
"""Set the name of this circuit breaker."""
161
```
162
163
### Exception Management
164
165
Configuration and management of exceptions that should be excluded from circuit breaker failure logic, typically for business exceptions.
166
167
```python { .api }
168
@property
169
def excluded_exceptions(self) -> tuple:
170
"""List of excluded exceptions that don't count as system failures."""
171
172
def add_excluded_exception(self, exception) -> None:
173
"""
174
Add an exception type to the exclusion list.
175
176
Args:
177
exception: Exception type to exclude from failure counting
178
"""
179
180
def add_excluded_exceptions(self, *exceptions) -> None:
181
"""
182
Add multiple exception types to the exclusion list.
183
184
Args:
185
*exceptions: Exception types to exclude from failure counting
186
"""
187
188
def remove_excluded_exception(self, exception) -> None:
189
"""
190
Remove an exception type from the exclusion list.
191
192
Args:
193
exception: Exception type to remove from exclusion list
194
"""
195
196
def is_system_error(self, exception) -> bool:
197
"""
198
Check if an exception should be considered a system error.
199
200
Args:
201
exception: The exception to check
202
203
Returns:
204
bool: True if exception counts as system error, False if excluded
205
"""
206
```
207
208
## Usage Examples
209
210
### Basic Circuit Breaker
211
212
```python
213
import pybreaker
214
215
# Create circuit breaker
216
breaker = pybreaker.CircuitBreaker(fail_max=3, reset_timeout=30)
217
218
# Use as decorator
219
@breaker
220
def database_call():
221
# Database operation that might fail
222
pass
223
224
# Use with direct call
225
def api_call():
226
# API call that might fail
227
pass
228
229
result = breaker.call(api_call)
230
231
# Use as context manager
232
with breaker.calling():
233
# Some operation that might fail
234
pass
235
```
236
237
### Custom Configuration
238
239
```python
240
import pybreaker
241
242
# Custom circuit breaker with specific settings
243
breaker = pybreaker.CircuitBreaker(
244
fail_max=10, # Allow 10 failures
245
reset_timeout=120, # Wait 2 minutes before trial
246
success_threshold=3, # Need 3 successes to fully close
247
name="payment_service",
248
throw_new_error_on_trip=False # Return original error
249
)
250
251
@breaker
252
def process_payment(amount, account):
253
# Payment processing logic
254
pass
255
```
256
257
### Monitoring and Management
258
259
```python
260
import pybreaker
261
262
breaker = pybreaker.CircuitBreaker(name="user_service")
263
264
# Monitor circuit state
265
print(f"Current state: {breaker.current_state}")
266
print(f"Failure count: {breaker.fail_counter}")
267
print(f"Success count: {breaker.success_counter}")
268
269
# Manual state management
270
if breaker.current_state == "open":
271
print("Service is down, manually closing for maintenance")
272
breaker.close()
273
274
# Adjust thresholds dynamically
275
if high_load_detected():
276
breaker.fail_max = 15 # Be more tolerant during high load
277
```