-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcircuit_breaker.py
More file actions
90 lines (73 loc) · 2.94 KB
/
Copy pathcircuit_breaker.py
File metadata and controls
90 lines (73 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
"""Circuit breaker example for Streamline Python SDK.
The circuit breaker prevents your application from repeatedly attempting
operations against a failing server. After consecutive failures it "opens"
and rejects requests immediately, giving the server time to recover.
Run with:
python examples/circuit_breaker.py
"""
import asyncio
import os
from streamline_sdk import StreamlineClient
from streamline_sdk.circuit_breaker import (
CircuitBreaker,
CircuitBreakerConfig,
CircuitBreakerOpen,
CircuitState,
)
async def main():
print("Circuit Breaker Example")
print("=" * 40)
# Configure the circuit breaker
cb_config = CircuitBreakerConfig(
failure_threshold=5, # Open after 5 consecutive failures
success_threshold=2, # Close after 2 successes in half-open
open_timeout_s=10.0, # Wait 10s before probing
half_open_max_requests=3, # Allow 3 probe requests in half-open
on_state_change=lambda old, new: print(
f" [Circuit Breaker] {old.value} → {new.value}"
),
)
breaker = CircuitBreaker(config=cb_config)
async with StreamlineClient(
bootstrap_servers=os.environ.get("STREAMLINE_BOOTSTRAP_SERVERS", "localhost:9092"),
) as client:
print(f"Connected. Circuit state: {breaker.state.value}")
# Create topic
from streamline_sdk.admin import TopicConfig
try:
await client.admin.create_topic(TopicConfig(name="cb-example", num_partitions=1))
except Exception:
pass # topic may already exist
# Send messages through the circuit breaker
for i in range(20):
if not breaker.allow():
print(f" Message {i}: REJECTED (circuit open)")
await asyncio.sleep(1)
continue
try:
result = await client.producer.send(
"cb-example",
value=f"message-{i}".encode(),
key=f"key-{i}".encode(),
)
breaker.record_success()
print(
f" Message {i}: sent to partition={result.partition} "
f"offset={result.offset} (circuit: {breaker.state.value})"
)
except CircuitBreakerOpen:
print(f" Message {i}: circuit breaker is OPEN")
except Exception as e:
breaker.record_failure()
print(f" Message {i}: FAILED ({e}) (circuit: {breaker.state.value})")
# Show final state
successes, failures = breaker.counts
print(f"\nFinal circuit state: {breaker.state.value}")
print(f"Successes: {successes}, Failures: {failures}")
# Manual reset
if breaker.state == CircuitState.OPEN:
breaker.reset()
print(f"Circuit manually reset to: {breaker.state.value}")
print("\nDone!")
if __name__ == "__main__":
asyncio.run(main())