From 8161a380bd7a618cf5aa594a22c10bba20e4c91d Mon Sep 17 00:00:00 2001 From: Ivan Zuzak Date: Sat, 9 Aug 2025 23:11:09 +0200 Subject: [PATCH] Fix circuit breaker recovery - Use error_threshold_timeout when filtering observed errors - Clear errors when closing circuit upon reaching success_threshold --- lib/redis_client/circuit_breaker.rb | 3 ++- test/redis_client/circuit_breaker_test.rb | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/redis_client/circuit_breaker.rb b/lib/redis_client/circuit_breaker.rb index 5d68a4f..af3c1a9 100644 --- a/lib/redis_client/circuit_breaker.rb +++ b/lib/redis_client/circuit_breaker.rb @@ -79,7 +79,7 @@ def refresh_state def record_error now = RedisClient.now - expiry = now - @error_timeout + expiry = now - @error_threshold_timeout @lock.synchronize do if @state == :closed @errors.reject! { |t| t < expiry } @@ -100,6 +100,7 @@ def record_success @successes += 1 if @successes >= @success_threshold + @errors.clear @state = :closed end end diff --git a/test/redis_client/circuit_breaker_test.rb b/test/redis_client/circuit_breaker_test.rb index aadf33b..c56ec63 100644 --- a/test/redis_client/circuit_breaker_test.rb +++ b/test/redis_client/circuit_breaker_test.rb @@ -21,6 +21,18 @@ def test_open_circuit_after_consecutive_errors assert_open @circuit_breaker end + def test_track_errors_during_error_threshold_window + assert_closed @circuit_breaker + (@circuit_breaker.error_threshold - 1).times do + record_error @circuit_breaker + end + + travel(@circuit_breaker.error_threshold_timeout - 0.01) do + record_error @circuit_breaker + assert_open @circuit_breaker + end + end + def test_allow_use_after_the_errors_timedout open_circuit @circuit_breaker assert_open @circuit_breaker