From 0196b9a9bd48756e3ea06c80bec0fee341284612 Mon Sep 17 00:00:00 2001 From: Nedyalko Dyakov Date: Thu, 4 Sep 2025 17:51:28 +0300 Subject: [PATCH] DialTimeout defaults back to 5 seconds --- hitless/circuit_breaker_test.go | 80 ++++++++++++++++----------------- hitless/config_test.go | 6 +-- internal/pool/pool_test.go | 2 +- options.go | 4 +- 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/hitless/circuit_breaker_test.go b/hitless/circuit_breaker_test.go index 16015ec8..385eb135 100644 --- a/hitless/circuit_breaker_test.go +++ b/hitless/circuit_breaker_test.go @@ -18,11 +18,11 @@ func TestCircuitBreaker(t *testing.T) { t.Run("InitialState", func(t *testing.T) { cb := newCircuitBreaker("test-endpoint:6379", config) - + if cb.IsOpen() { t.Error("Circuit breaker should start in closed state") } - + if cb.GetState() != CircuitBreakerClosed { t.Errorf("Expected state %v, got %v", CircuitBreakerClosed, cb.GetState()) } @@ -30,15 +30,15 @@ func TestCircuitBreaker(t *testing.T) { t.Run("SuccessfulExecution", func(t *testing.T) { cb := newCircuitBreaker("test-endpoint:6379", config) - + err := cb.Execute(func() error { return nil // Success }) - + if err != nil { t.Errorf("Expected no error, got %v", err) } - + if cb.GetState() != CircuitBreakerClosed { t.Errorf("Expected state %v, got %v", CircuitBreakerClosed, cb.GetState()) } @@ -77,18 +77,18 @@ func TestCircuitBreaker(t *testing.T) { t.Run("OpenCircuitFailsFast", func(t *testing.T) { cb := newCircuitBreaker("test-endpoint:6379", config) testError := errors.New("test error") - + // Force circuit to open for i := 0; i < 5; i++ { cb.Execute(func() error { return testError }) } - + // Now it should fail fast err := cb.Execute(func() error { t.Error("Function should not be called when circuit is open") return nil }) - + if err != ErrCircuitBreakerOpen { t.Errorf("Expected ErrCircuitBreakerOpen, got %v", err) } @@ -103,30 +103,30 @@ func TestCircuitBreaker(t *testing.T) { } cb := newCircuitBreaker("test-endpoint:6379", testConfig) testError := errors.New("test error") - + // Force circuit to open for i := 0; i < 5; i++ { cb.Execute(func() error { return testError }) } - + if cb.GetState() != CircuitBreakerOpen { t.Error("Circuit should be open") } - + // Wait for reset timeout time.Sleep(150 * time.Millisecond) - + // Next call should transition to half-open executed := false err := cb.Execute(func() error { executed = true return nil // Success }) - + if err != nil { t.Errorf("Expected no error, got %v", err) } - + if !executed { t.Error("Function should have been executed in half-open state") } @@ -141,15 +141,15 @@ func TestCircuitBreaker(t *testing.T) { } cb := newCircuitBreaker("test-endpoint:6379", testConfig) testError := errors.New("test error") - + // Force circuit to open for i := 0; i < 5; i++ { cb.Execute(func() error { return testError }) } - + // Wait for reset timeout time.Sleep(100 * time.Millisecond) - + // Execute successful requests in half-open state for i := 0; i < 3; i++ { err := cb.Execute(func() error { @@ -159,7 +159,7 @@ func TestCircuitBreaker(t *testing.T) { t.Errorf("Expected no error on attempt %d, got %v", i+1, err) } } - + // Circuit should now be closed if cb.GetState() != CircuitBreakerClosed { t.Errorf("Expected state %v, got %v", CircuitBreakerClosed, cb.GetState()) @@ -175,24 +175,24 @@ func TestCircuitBreaker(t *testing.T) { } cb := newCircuitBreaker("test-endpoint:6379", testConfig) testError := errors.New("test error") - + // Force circuit to open for i := 0; i < 5; i++ { cb.Execute(func() error { return testError }) } - + // Wait for reset timeout time.Sleep(100 * time.Millisecond) - + // First request in half-open state fails err := cb.Execute(func() error { return testError }) - + if err != testError { t.Errorf("Expected test error, got %v", err) } - + // Circuit should be open again if cb.GetState() != CircuitBreakerOpen { t.Errorf("Expected state %v, got %v", CircuitBreakerOpen, cb.GetState()) @@ -204,8 +204,8 @@ func TestCircuitBreaker(t *testing.T) { testError := errors.New("test error") // Execute some operations - cb.Execute(func() error { return testError }) // Failure - cb.Execute(func() error { return testError }) // Failure + cb.Execute(func() error { return testError }) // Failure + cb.Execute(func() error { return testError }) // Failure stats := cb.GetStats() @@ -241,15 +241,15 @@ func TestCircuitBreakerManager(t *testing.T) { t.Run("GetCircuitBreaker", func(t *testing.T) { manager := newCircuitBreakerManager(config) - + cb1 := manager.GetCircuitBreaker("endpoint1:6379") cb2 := manager.GetCircuitBreaker("endpoint2:6379") cb3 := manager.GetCircuitBreaker("endpoint1:6379") // Same as cb1 - + if cb1 == cb2 { t.Error("Different endpoints should have different circuit breakers") } - + if cb1 != cb3 { t.Error("Same endpoint should return the same circuit breaker") } @@ -257,27 +257,27 @@ func TestCircuitBreakerManager(t *testing.T) { t.Run("GetAllStats", func(t *testing.T) { manager := newCircuitBreakerManager(config) - + // Create circuit breakers for different endpoints cb1 := manager.GetCircuitBreaker("endpoint1:6379") cb2 := manager.GetCircuitBreaker("endpoint2:6379") - + // Execute some operations cb1.Execute(func() error { return nil }) cb2.Execute(func() error { return errors.New("test error") }) - + stats := manager.GetAllStats() - + if len(stats) != 2 { t.Errorf("Expected 2 circuit breaker stats, got %d", len(stats)) } - + // Check that we have stats for both endpoints endpoints := make(map[string]bool) for _, stat := range stats { endpoints[stat.Endpoint] = true } - + if !endpoints["endpoint1:6379"] || !endpoints["endpoint2:6379"] { t.Error("Missing stats for expected endpoints") } @@ -286,25 +286,25 @@ func TestCircuitBreakerManager(t *testing.T) { t.Run("Reset", func(t *testing.T) { manager := newCircuitBreakerManager(config) testError := errors.New("test error") - + cb := manager.GetCircuitBreaker("test-endpoint:6379") - + // Force circuit to open for i := 0; i < 5; i++ { cb.Execute(func() error { return testError }) } - + if cb.GetState() != CircuitBreakerOpen { t.Error("Circuit should be open") } - + // Reset all circuit breakers manager.Reset() - + if cb.GetState() != CircuitBreakerClosed { t.Error("Circuit should be closed after reset") } - + if cb.failures.Load() != 0 { t.Error("Failure count should be reset to 0") } diff --git a/hitless/config_test.go b/hitless/config_test.go index 6c74823c..ddae059e 100644 --- a/hitless/config_test.go +++ b/hitless/config_test.go @@ -171,7 +171,7 @@ func TestApplyDefaults(t *testing.T) { } resultCapped := configWithLargeQueue.ApplyDefaultsWithPoolSize(20) // Small pool size - expectedCap := 20 * 5 // 5x pool size = 100 + expectedCap := 20 * 5 // 5x pool size = 100 if resultCapped.HandoffQueueSize != expectedCap { t.Errorf("Expected HandoffQueueSize to be capped by 5x pool size (%d), got %d", expectedCap, resultCapped.HandoffQueueSize) } @@ -194,7 +194,7 @@ func TestApplyDefaults(t *testing.T) { } resultVeryLarge := configWithVeryLargeQueue.ApplyDefaultsWithPoolSize(100) // Pool size 100 - expectedVeryLargeCap := 100 * 5 // 5x pool size = 500 + expectedVeryLargeCap := 100 * 5 // 5x pool size = 500 if resultVeryLarge.HandoffQueueSize != expectedVeryLargeCap { t.Errorf("Expected very large HandoffQueueSize to be capped by 5x pool size (%d), got %d", expectedVeryLargeCap, resultVeryLarge.HandoffQueueSize) } @@ -305,7 +305,7 @@ func TestIntegrationWithApplyDefaults(t *testing.T) { t.Run("ProcessorWithPartialConfigAppliesDefaults", func(t *testing.T) { // Create a partial config with only some fields set partialConfig := &Config{ - MaxWorkers: 15, // Custom value (>= 10 to test preservation) + MaxWorkers: 15, // Custom value (>= 10 to test preservation) LogLevel: logging.LogLevelInfo, // Custom value // Other fields left as zero values - should get defaults } diff --git a/internal/pool/pool_test.go b/internal/pool/pool_test.go index 6a7870b5..ef1ed5f9 100644 --- a/internal/pool/pool_test.go +++ b/internal/pool/pool_test.go @@ -454,7 +454,7 @@ func TestDialerRetryConfiguration(t *testing.T) { PoolSize: 1, PoolTimeout: time.Second, DialTimeout: time.Second, - DialerRetries: 3, // Custom retry count + DialerRetries: 3, // Custom retry count DialerRetryTimeout: 10 * time.Millisecond, // Fast retries for testing }) defer connPool.Close() diff --git a/options.go b/options.go index 0e154ac0..eb0bc190 100644 --- a/options.go +++ b/options.go @@ -109,7 +109,7 @@ type Options struct { // DialTimeout for establishing new connections. // - // default: 10 seconds + // default: 5 seconds DialTimeout time.Duration // DialerRetries is the maximum number of retry attempts when dialing fails. @@ -285,7 +285,7 @@ func (opt *Options) init() { opt.Protocol = 3 } if opt.DialTimeout == 0 { - opt.DialTimeout = 10 * time.Second + opt.DialTimeout = 5 * time.Second } if opt.DialerRetries == 0 { opt.DialerRetries = 5