diff --git a/cluster.go b/cluster.go index 43354d77..c81fc1d5 100644 --- a/cluster.go +++ b/cluster.go @@ -656,7 +656,7 @@ func (c *ClusterClient) Process(cmd Cmder) error { continue } - if internal.IsRetryableError(err) { + if internal.IsRetryableError(err, true) { var nodeErr error node, nodeErr = c.nodes.Random() if nodeErr != nil { diff --git a/commands.go b/commands.go index 7f0000f3..a3b90f12 100644 --- a/commands.go +++ b/commands.go @@ -11,7 +11,7 @@ func readTimeout(timeout time.Duration) time.Duration { if timeout == 0 { return 0 } - return timeout + time.Second + return timeout + 10*time.Second } func usePrecise(dur time.Duration) bool { diff --git a/internal/error.go b/internal/error.go index e1b8be6b..0898eeb6 100644 --- a/internal/error.go +++ b/internal/error.go @@ -12,9 +12,9 @@ type RedisError string func (e RedisError) Error() string { return string(e) } -func IsRetryableError(err error) bool { +func IsRetryableError(err error, retryNetError bool) bool { if IsNetworkError(err) { - return true + return retryNetError } s := err.Error() if s == "ERR max number of clients reached" { diff --git a/redis.go b/redis.go index 615bf28d..230091b3 100644 --- a/redis.go +++ b/redis.go @@ -136,7 +136,7 @@ func (c *baseClient) defaultProcess(cmd Cmder) error { cn, _, err := c.getConn() if err != nil { cmd.setErr(err) - if internal.IsRetryableError(err) { + if internal.IsRetryableError(err, true) { continue } return err @@ -146,7 +146,7 @@ func (c *baseClient) defaultProcess(cmd Cmder) error { if err := writeCmd(cn, cmd); err != nil { c.releaseConn(cn, err) cmd.setErr(err) - if internal.IsRetryableError(err) { + if internal.IsRetryableError(err, true) { continue } return err @@ -155,7 +155,7 @@ func (c *baseClient) defaultProcess(cmd Cmder) error { cn.SetReadTimeout(c.cmdTimeout(cmd)) err = cmd.readReply(cn) c.releaseConn(cn, err) - if err != nil && internal.IsRetryableError(err) { + if err != nil && internal.IsRetryableError(err, cmd.readTimeout() == nil) { continue } @@ -221,7 +221,7 @@ func (c *baseClient) pipelineExecer(p pipelineProcessor) pipelineExecer { } _ = c.connPool.Remove(cn) - if !canRetry || !internal.IsRetryableError(err) { + if !canRetry || !internal.IsRetryableError(err, true) { break } } diff --git a/ring.go b/ring.go index a058630f..a30c3210 100644 --- a/ring.go +++ b/ring.go @@ -477,7 +477,7 @@ func (c *Ring) pipelineExec(cmds []Cmder) error { } _ = shard.Client.connPool.Remove(cn) - if canRetry && internal.IsRetryableError(err) { + if canRetry && internal.IsRetryableError(err, true) { if failedCmdsMap == nil { failedCmdsMap = make(map[string][]Cmder) }