1
0
mirror of https://github.com/redis/go-redis.git synced 2025-09-08 19:52:07 +03:00

DialTimeout defaults back to 5 seconds

This commit is contained in:
Nedyalko Dyakov
2025-09-04 17:51:28 +03:00
parent 8aecdb890a
commit 0196b9a9bd
4 changed files with 46 additions and 46 deletions

View File

@@ -18,11 +18,11 @@ func TestCircuitBreaker(t *testing.T) {
t.Run("InitialState", func(t *testing.T) { t.Run("InitialState", func(t *testing.T) {
cb := newCircuitBreaker("test-endpoint:6379", config) cb := newCircuitBreaker("test-endpoint:6379", config)
if cb.IsOpen() { if cb.IsOpen() {
t.Error("Circuit breaker should start in closed state") t.Error("Circuit breaker should start in closed state")
} }
if cb.GetState() != CircuitBreakerClosed { if cb.GetState() != CircuitBreakerClosed {
t.Errorf("Expected state %v, got %v", CircuitBreakerClosed, cb.GetState()) 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) { t.Run("SuccessfulExecution", func(t *testing.T) {
cb := newCircuitBreaker("test-endpoint:6379", config) cb := newCircuitBreaker("test-endpoint:6379", config)
err := cb.Execute(func() error { err := cb.Execute(func() error {
return nil // Success return nil // Success
}) })
if err != nil { if err != nil {
t.Errorf("Expected no error, got %v", err) t.Errorf("Expected no error, got %v", err)
} }
if cb.GetState() != CircuitBreakerClosed { if cb.GetState() != CircuitBreakerClosed {
t.Errorf("Expected state %v, got %v", CircuitBreakerClosed, cb.GetState()) 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) { t.Run("OpenCircuitFailsFast", func(t *testing.T) {
cb := newCircuitBreaker("test-endpoint:6379", config) cb := newCircuitBreaker("test-endpoint:6379", config)
testError := errors.New("test error") testError := errors.New("test error")
// Force circuit to open // Force circuit to open
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
cb.Execute(func() error { return testError }) cb.Execute(func() error { return testError })
} }
// Now it should fail fast // Now it should fail fast
err := cb.Execute(func() error { err := cb.Execute(func() error {
t.Error("Function should not be called when circuit is open") t.Error("Function should not be called when circuit is open")
return nil return nil
}) })
if err != ErrCircuitBreakerOpen { if err != ErrCircuitBreakerOpen {
t.Errorf("Expected ErrCircuitBreakerOpen, got %v", err) t.Errorf("Expected ErrCircuitBreakerOpen, got %v", err)
} }
@@ -103,30 +103,30 @@ func TestCircuitBreaker(t *testing.T) {
} }
cb := newCircuitBreaker("test-endpoint:6379", testConfig) cb := newCircuitBreaker("test-endpoint:6379", testConfig)
testError := errors.New("test error") testError := errors.New("test error")
// Force circuit to open // Force circuit to open
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
cb.Execute(func() error { return testError }) cb.Execute(func() error { return testError })
} }
if cb.GetState() != CircuitBreakerOpen { if cb.GetState() != CircuitBreakerOpen {
t.Error("Circuit should be open") t.Error("Circuit should be open")
} }
// Wait for reset timeout // Wait for reset timeout
time.Sleep(150 * time.Millisecond) time.Sleep(150 * time.Millisecond)
// Next call should transition to half-open // Next call should transition to half-open
executed := false executed := false
err := cb.Execute(func() error { err := cb.Execute(func() error {
executed = true executed = true
return nil // Success return nil // Success
}) })
if err != nil { if err != nil {
t.Errorf("Expected no error, got %v", err) t.Errorf("Expected no error, got %v", err)
} }
if !executed { if !executed {
t.Error("Function should have been executed in half-open state") 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) cb := newCircuitBreaker("test-endpoint:6379", testConfig)
testError := errors.New("test error") testError := errors.New("test error")
// Force circuit to open // Force circuit to open
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
cb.Execute(func() error { return testError }) cb.Execute(func() error { return testError })
} }
// Wait for reset timeout // Wait for reset timeout
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
// Execute successful requests in half-open state // Execute successful requests in half-open state
for i := 0; i < 3; i++ { for i := 0; i < 3; i++ {
err := cb.Execute(func() error { 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) t.Errorf("Expected no error on attempt %d, got %v", i+1, err)
} }
} }
// Circuit should now be closed // Circuit should now be closed
if cb.GetState() != CircuitBreakerClosed { if cb.GetState() != CircuitBreakerClosed {
t.Errorf("Expected state %v, got %v", CircuitBreakerClosed, cb.GetState()) 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) cb := newCircuitBreaker("test-endpoint:6379", testConfig)
testError := errors.New("test error") testError := errors.New("test error")
// Force circuit to open // Force circuit to open
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
cb.Execute(func() error { return testError }) cb.Execute(func() error { return testError })
} }
// Wait for reset timeout // Wait for reset timeout
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
// First request in half-open state fails // First request in half-open state fails
err := cb.Execute(func() error { err := cb.Execute(func() error {
return testError return testError
}) })
if err != testError { if err != testError {
t.Errorf("Expected test error, got %v", err) t.Errorf("Expected test error, got %v", err)
} }
// Circuit should be open again // Circuit should be open again
if cb.GetState() != CircuitBreakerOpen { if cb.GetState() != CircuitBreakerOpen {
t.Errorf("Expected state %v, got %v", CircuitBreakerOpen, cb.GetState()) t.Errorf("Expected state %v, got %v", CircuitBreakerOpen, cb.GetState())
@@ -204,8 +204,8 @@ func TestCircuitBreaker(t *testing.T) {
testError := errors.New("test error") testError := errors.New("test error")
// Execute some operations // 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() stats := cb.GetStats()
@@ -241,15 +241,15 @@ func TestCircuitBreakerManager(t *testing.T) {
t.Run("GetCircuitBreaker", func(t *testing.T) { t.Run("GetCircuitBreaker", func(t *testing.T) {
manager := newCircuitBreakerManager(config) manager := newCircuitBreakerManager(config)
cb1 := manager.GetCircuitBreaker("endpoint1:6379") cb1 := manager.GetCircuitBreaker("endpoint1:6379")
cb2 := manager.GetCircuitBreaker("endpoint2:6379") cb2 := manager.GetCircuitBreaker("endpoint2:6379")
cb3 := manager.GetCircuitBreaker("endpoint1:6379") // Same as cb1 cb3 := manager.GetCircuitBreaker("endpoint1:6379") // Same as cb1
if cb1 == cb2 { if cb1 == cb2 {
t.Error("Different endpoints should have different circuit breakers") t.Error("Different endpoints should have different circuit breakers")
} }
if cb1 != cb3 { if cb1 != cb3 {
t.Error("Same endpoint should return the same circuit breaker") 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) { t.Run("GetAllStats", func(t *testing.T) {
manager := newCircuitBreakerManager(config) manager := newCircuitBreakerManager(config)
// Create circuit breakers for different endpoints // Create circuit breakers for different endpoints
cb1 := manager.GetCircuitBreaker("endpoint1:6379") cb1 := manager.GetCircuitBreaker("endpoint1:6379")
cb2 := manager.GetCircuitBreaker("endpoint2:6379") cb2 := manager.GetCircuitBreaker("endpoint2:6379")
// Execute some operations // Execute some operations
cb1.Execute(func() error { return nil }) cb1.Execute(func() error { return nil })
cb2.Execute(func() error { return errors.New("test error") }) cb2.Execute(func() error { return errors.New("test error") })
stats := manager.GetAllStats() stats := manager.GetAllStats()
if len(stats) != 2 { if len(stats) != 2 {
t.Errorf("Expected 2 circuit breaker stats, got %d", len(stats)) t.Errorf("Expected 2 circuit breaker stats, got %d", len(stats))
} }
// Check that we have stats for both endpoints // Check that we have stats for both endpoints
endpoints := make(map[string]bool) endpoints := make(map[string]bool)
for _, stat := range stats { for _, stat := range stats {
endpoints[stat.Endpoint] = true endpoints[stat.Endpoint] = true
} }
if !endpoints["endpoint1:6379"] || !endpoints["endpoint2:6379"] { if !endpoints["endpoint1:6379"] || !endpoints["endpoint2:6379"] {
t.Error("Missing stats for expected endpoints") t.Error("Missing stats for expected endpoints")
} }
@@ -286,25 +286,25 @@ func TestCircuitBreakerManager(t *testing.T) {
t.Run("Reset", func(t *testing.T) { t.Run("Reset", func(t *testing.T) {
manager := newCircuitBreakerManager(config) manager := newCircuitBreakerManager(config)
testError := errors.New("test error") testError := errors.New("test error")
cb := manager.GetCircuitBreaker("test-endpoint:6379") cb := manager.GetCircuitBreaker("test-endpoint:6379")
// Force circuit to open // Force circuit to open
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
cb.Execute(func() error { return testError }) cb.Execute(func() error { return testError })
} }
if cb.GetState() != CircuitBreakerOpen { if cb.GetState() != CircuitBreakerOpen {
t.Error("Circuit should be open") t.Error("Circuit should be open")
} }
// Reset all circuit breakers // Reset all circuit breakers
manager.Reset() manager.Reset()
if cb.GetState() != CircuitBreakerClosed { if cb.GetState() != CircuitBreakerClosed {
t.Error("Circuit should be closed after reset") t.Error("Circuit should be closed after reset")
} }
if cb.failures.Load() != 0 { if cb.failures.Load() != 0 {
t.Error("Failure count should be reset to 0") t.Error("Failure count should be reset to 0")
} }

View File

@@ -171,7 +171,7 @@ func TestApplyDefaults(t *testing.T) {
} }
resultCapped := configWithLargeQueue.ApplyDefaultsWithPoolSize(20) // Small pool size 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 { if resultCapped.HandoffQueueSize != expectedCap {
t.Errorf("Expected HandoffQueueSize to be capped by 5x pool size (%d), got %d", expectedCap, resultCapped.HandoffQueueSize) 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 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 { if resultVeryLarge.HandoffQueueSize != expectedVeryLargeCap {
t.Errorf("Expected very large HandoffQueueSize to be capped by 5x pool size (%d), got %d", expectedVeryLargeCap, resultVeryLarge.HandoffQueueSize) 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) { t.Run("ProcessorWithPartialConfigAppliesDefaults", func(t *testing.T) {
// Create a partial config with only some fields set // Create a partial config with only some fields set
partialConfig := &Config{ partialConfig := &Config{
MaxWorkers: 15, // Custom value (>= 10 to test preservation) MaxWorkers: 15, // Custom value (>= 10 to test preservation)
LogLevel: logging.LogLevelInfo, // Custom value LogLevel: logging.LogLevelInfo, // Custom value
// Other fields left as zero values - should get defaults // Other fields left as zero values - should get defaults
} }

View File

@@ -454,7 +454,7 @@ func TestDialerRetryConfiguration(t *testing.T) {
PoolSize: 1, PoolSize: 1,
PoolTimeout: time.Second, PoolTimeout: time.Second,
DialTimeout: time.Second, DialTimeout: time.Second,
DialerRetries: 3, // Custom retry count DialerRetries: 3, // Custom retry count
DialerRetryTimeout: 10 * time.Millisecond, // Fast retries for testing DialerRetryTimeout: 10 * time.Millisecond, // Fast retries for testing
}) })
defer connPool.Close() defer connPool.Close()

View File

@@ -109,7 +109,7 @@ type Options struct {
// DialTimeout for establishing new connections. // DialTimeout for establishing new connections.
// //
// default: 10 seconds // default: 5 seconds
DialTimeout time.Duration DialTimeout time.Duration
// DialerRetries is the maximum number of retry attempts when dialing fails. // DialerRetries is the maximum number of retry attempts when dialing fails.
@@ -285,7 +285,7 @@ func (opt *Options) init() {
opt.Protocol = 3 opt.Protocol = 3
} }
if opt.DialTimeout == 0 { if opt.DialTimeout == 0 {
opt.DialTimeout = 10 * time.Second opt.DialTimeout = 5 * time.Second
} }
if opt.DialerRetries == 0 { if opt.DialerRetries == 0 {
opt.DialerRetries = 5 opt.DialerRetries = 5