Exercise 3: Half-Open Recovery — Possible Solution ==================================================================== THE EXTENDED CIRCUIT BREAKER ------------------------------ class CircuitBreakerHalfOpen: def __init__(self, failure_threshold=3, reset_timeout=0.05): ... self.opened_at = None def call(self, dependency_fn): if self.state == "OPEN": if time.time() - self.opened_at >= self.reset_timeout: self.state = "HALF_OPEN" # allow one trial call through else: raise RuntimeError("circuit open - failing fast") try: result = dependency_fn() if self.state == "HALF_OPEN": self.state = "CLOSED" # trial call succeeded, fully reset self.failure_count = 0 return result except Exception: self.failure_count += 1 if self.state == "HALF_OPEN": self.state = "OPEN" # trial call failed, back to OPEN self.opened_at = time.time() elif self.failure_count >= self.failure_threshold: self.state = "OPEN" self.opened_at = time.time() self.times_opened += 1 raise THE TEST ------------------------------ def test_half_open_recovery(): breaker = CircuitBreakerHalfOpen(failure_threshold=3, reset_timeout=0.05) for _ in range(3): try: breaker.call(failing_dependency) except (ConnectionError, RuntimeError): pass assert breaker.state == "OPEN" time.sleep(0.06) # enough time for reset_timeout to elapse result = breaker.call(healthy_dependency) # trial call during half-open assert result == "OK" assert breaker.state == "CLOSED" return True RESULT ------------------------------ test_half_open_recovery: PASS Three failures trip the breaker to OPEN. After the reset timeout elapses, the next call is allowed through as a trial (HALF_OPEN); since it succeeds, the breaker resets fully to CLOSED. WHY THIS WORKS AS AN ANSWER ------------------------------ This extends the chapter's own resilience-pattern testing principle one state further: proving a circuit breaker trips correctly (the chapter's own test) is only half the pattern - proving it also recovers correctly once the downstream dependency is healthy again is the other half, and just as invisible to any e2e happy-path test as the OPEN state itself was. A test suite that only verifies tripping, never recovery, would let a real bug (a breaker that gets stuck OPEN forever, or one that resets even when the dependency is still broken) ship unnoticed - exactly the same blind spot the chapter identified, one layer deeper into the same resilience pattern.