Skip to content

Commit 21a1f58

Browse files
committed
Retry timeout and retryable error
1 parent 16e62e0 commit 21a1f58

File tree

5 files changed

+23
-12
lines changed

5 files changed

+23
-12
lines changed

cluster.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ func (c *ClusterClient) _process(ctx context.Context, cmd Cmder) error {
810810
continue
811811
}
812812

813-
if isRetryableError(lastErr, cmd.readTimeout() == nil) {
813+
if shouldRetry(lastErr, cmd.readTimeout() == nil) {
814814
// First retry the same node.
815815
if attempt == 0 {
816816
continue
@@ -1466,7 +1466,7 @@ func (c *ClusterClient) Watch(ctx context.Context, fn func(*Tx) error, keys ...s
14661466
continue
14671467
}
14681468

1469-
if isRetryableError(err, true) {
1469+
if shouldRetry(err, true) {
14701470
continue
14711471
}
14721472

error.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@ type Error interface {
2424

2525
var _ Error = proto.RedisError("")
2626

27-
func isRetryableError(err error, retryTimeout bool) bool {
27+
func shouldRetry(err error, retryTimeout bool) bool {
2828
switch err {
29+
case io.EOF, io.ErrUnexpectedEOF:
30+
return true
2931
case nil, context.Canceled, context.DeadlineExceeded:
3032
return false
31-
case io.EOF:
32-
return true
3333
}
34-
if netErr, ok := err.(net.Error); ok {
35-
if netErr.Timeout() {
34+
35+
if v, ok := err.(timeoutError); ok {
36+
if v.Timeout() {
3637
return retryTimeout
3738
}
3839
return true
@@ -51,6 +52,7 @@ func isRetryableError(err error, retryTimeout bool) bool {
5152
if strings.HasPrefix(s, "CLUSTERDOWN ") {
5253
return true
5354
}
55+
5456
return false
5557
}
5658

@@ -63,16 +65,19 @@ func isBadConn(err error, allowTimeout bool) bool {
6365
if err == nil {
6466
return false
6567
}
68+
6669
if isRedisError(err) {
6770
// Close connections in read only state in case domain addr is used
6871
// and domain resolves to a different Redis Server. See #790.
6972
return isReadOnlyError(err)
7073
}
74+
7175
if allowTimeout {
7276
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
73-
return false
77+
return !netErr.Temporary()
7478
}
7579
}
80+
7681
return true
7782
}
7883

@@ -106,3 +111,9 @@ func isLoadingError(err error) bool {
106111
func isReadOnlyError(err error) bool {
107112
return strings.HasPrefix(err.Error(), "READONLY ")
108113
}
114+
115+
//------------------------------------------------------------------------------
116+
117+
type timeoutError interface {
118+
Timeout() bool
119+
}

main_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ func startSentinel(port, masterName, masterPort string) (*redisProcess, error) {
332332
type badConnError string
333333

334334
func (e badConnError) Error() string { return string(e) }
335-
func (e badConnError) Timeout() bool { return false }
335+
func (e badConnError) Timeout() bool { return true }
336336
func (e badConnError) Temporary() bool { return false }
337337

338338
type badConn struct {

redis.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ func (c *baseClient) _process(ctx context.Context, cmd Cmder) error {
345345
if err == nil {
346346
return nil
347347
}
348-
retry = isRetryableError(err, retryTimeout)
348+
retry = shouldRetry(err, retryTimeout)
349349
return err
350350
})
351351
if err == nil || !retry {
@@ -430,7 +430,7 @@ func (c *baseClient) _generalProcessPipeline(
430430
canRetry, err = p(ctx, cn, cmds)
431431
return err
432432
})
433-
if lastErr == nil || !canRetry || !isRetryableError(lastErr, true) {
433+
if lastErr == nil || !canRetry || !shouldRetry(lastErr, true) {
434434
return lastErr
435435
}
436436
}

ring.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ func (c *Ring) _process(ctx context.Context, cmd Cmder) error {
597597
}
598598

599599
lastErr = shard.Client.Process(ctx, cmd)
600-
if lastErr == nil || !isRetryableError(lastErr, cmd.readTimeout() == nil) {
600+
if lastErr == nil || !shouldRetry(lastErr, cmd.readTimeout() == nil) {
601601
return lastErr
602602
}
603603
}

0 commit comments

Comments
 (0)