Skip to content

Commit 4f09082

Browse files
monkey92tndyakov
andauthored
fix: connection pool timeout, increase retries (#3298)
* fix: connection pool timeout, increase retries Signed-off-by: monkey <[email protected]> * fix: add shouldRetry test Signed-off-by: monkey <[email protected]> --------- Signed-off-by: monkey <[email protected]> Co-authored-by: Nedyalko Dyakov <[email protected]>
1 parent 1c9309f commit 4f09082

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

error.go

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ func shouldRetry(err error, retryTimeout bool) bool {
5353
return true
5454
case nil, context.Canceled, context.DeadlineExceeded:
5555
return false
56+
case pool.ErrPoolTimeout:
57+
// connection pool timeout, increase retries. #3289
58+
return true
5659
}
5760

5861
if v, ok := err.(timeoutError); ok {

error_test.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package redis_test
2+
3+
import (
4+
"context"
5+
"errors"
6+
"io"
7+
8+
. "github.com/bsm/ginkgo/v2"
9+
. "github.com/bsm/gomega"
10+
"github.com/redis/go-redis/v9"
11+
)
12+
13+
type testTimeout struct {
14+
timeout bool
15+
}
16+
17+
func (t testTimeout) Timeout() bool {
18+
return t.timeout
19+
}
20+
21+
func (t testTimeout) Error() string {
22+
return "test timeout"
23+
}
24+
25+
var _ = Describe("error", func() {
26+
BeforeEach(func() {
27+
28+
})
29+
30+
AfterEach(func() {
31+
32+
})
33+
34+
It("should retry", func() {
35+
data := map[error]bool{
36+
io.EOF: true,
37+
io.ErrUnexpectedEOF: true,
38+
nil: false,
39+
context.Canceled: false,
40+
context.DeadlineExceeded: false,
41+
redis.ErrPoolTimeout: true,
42+
errors.New("ERR max number of clients reached"): true,
43+
errors.New("LOADING Redis is loading the dataset in memory"): true,
44+
errors.New("READONLY You can't write against a read only replica"): true,
45+
errors.New("CLUSTERDOWN The cluster is down"): true,
46+
errors.New("TRYAGAIN Command cannot be processed, please try again"): true,
47+
errors.New("other"): false,
48+
}
49+
50+
for err, expected := range data {
51+
Expect(redis.ShouldRetry(err, false)).To(Equal(expected))
52+
Expect(redis.ShouldRetry(err, true)).To(Equal(expected))
53+
}
54+
})
55+
56+
It("should retry timeout", func() {
57+
t1 := testTimeout{timeout: true}
58+
Expect(redis.ShouldRetry(t1, true)).To(Equal(true))
59+
Expect(redis.ShouldRetry(t1, false)).To(Equal(false))
60+
61+
t2 := testTimeout{timeout: false}
62+
Expect(redis.ShouldRetry(t2, true)).To(Equal(true))
63+
Expect(redis.ShouldRetry(t2, false)).To(Equal(true))
64+
})
65+
})

export_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"github.com/redis/go-redis/v9/internal/pool"
1212
)
1313

14+
var ErrPoolTimeout = pool.ErrPoolTimeout
15+
1416
func (c *baseClient) Pool() pool.Pooler {
1517
return c.connPool
1618
}
@@ -102,3 +104,7 @@ func (c *Ring) ShardByName(name string) *ringShard {
102104
func (c *ModuleLoadexConfig) ToArgs() []interface{} {
103105
return c.toArgs()
104106
}
107+
108+
func ShouldRetry(err error, retryTimeout bool) bool {
109+
return shouldRetry(err, retryTimeout)
110+
}

0 commit comments

Comments
 (0)