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:
@@ -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")
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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()
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user