CircuitBreaker: measure the failure window from the previous failure

last_failure_time_ was updated before IsWindowExpired() read it, so the
window never expired and widely spaced failures still opened the
breaker.

Audit finding D8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
This commit is contained in:
Claude
2026-09-24 09:16:04 -07:00
committed by Kyle Isom
parent f36aa9f456
commit 1bdc04ce1a
+5 -3
View File
@@ -73,13 +73,15 @@ CircuitBreaker::RecordFailure()
{ {
std::lock_guard<std::mutex> lg(mtx_); std::lock_guard<std::mutex> lg(mtx_);
const auto now = std::chrono::steady_clock::now(); // The window is measured from the previous failure, so check it before
last_failure_time_ = now; // recording this one.
const bool window_expired = IsWindowExpired();
last_failure_time_ = std::chrono::steady_clock::now();
switch (state_) { switch (state_) {
case State::Closed: case State::Closed:
// Check if we need to reset the failure count (window expired) // Check if we need to reset the failure count (window expired)
if (IsWindowExpired()) { if (window_expired) {
failure_count_ = 0; failure_count_ = 0;
} }