diff --git a/error.go b/error.go index a7bf159c2..82ad46d52 100644 --- a/error.go +++ b/error.go @@ -10,6 +10,7 @@ import ( "github.com/redis/go-redis/v9/internal" "github.com/redis/go-redis/v9/internal/pool" "github.com/redis/go-redis/v9/internal/proto" + "github.com/redis/go-redis/v9/internal/rand" ) // ErrClosed performs any operation on the closed client will return this error. @@ -87,30 +88,47 @@ func isRedisError(err error) bool { return ok } -func isBadConn(err error, allowTimeout bool, addr string) bool { +func isBadConn(ctx context.Context, err error, allowTimeout bool, addr string, shouldLog bool) bool { + // sample logging the error as it could get up to 1k errors per second + shouldLog = shouldLog && rand.Intn(100) == 0 switch err { case nil: + if shouldLog { + internal.Logger.Printf(ctx, "isBadConn: nil error: %v", err) + } return false case context.Canceled, context.DeadlineExceeded: + internal.Logger.Printf(ctx, "isBadConn: context error: %v", err) return true } if isRedisError(err) { switch { case isReadOnlyError(err): + if shouldLog { + internal.Logger.Printf(ctx, "isBadConn: is read-only error: %v", err) + } // Close connections in read only state in case domain addr is used // and domain resolves to a different Redis Server. See #790. return true case isMovedSameConnAddr(err, addr): + if shouldLog { + internal.Logger.Printf(ctx, "isBadConn: is isMovedSameConnAddr error: %v", err) + } // Close connections when we are asked to move to the same addr // of the connection. Force a DNS resolution when all connections // of the pool are recycled return true default: + if shouldLog { + internal.Logger.Printf(ctx, "isBadConn:other redis error: %v", err) + } return false } } - + if shouldLog { + internal.Logger.Printf(ctx, "go-redis:other error: %v", err) + } if allowTimeout { if netErr, ok := err.(net.Error); ok && netErr.Timeout() { return false diff --git a/osscluster.go b/osscluster.go index 1e9ee7de4..f410747d9 100644 --- a/osscluster.go +++ b/osscluster.go @@ -1374,7 +1374,7 @@ func (c *ClusterClient) processPipelineNodeConn( if err := cn.WithWriter(c.context(ctx), c.opt.WriteTimeout, func(wr *proto.Writer) error { return writeCmds(wr, cmds) }); err != nil { - if isBadConn(err, false, node.Client.getAddr()) { + if isBadConn(ctx, err, false, node.Client.getAddr(), false) { node.MarkAsFailing() } if shouldRetry(err, true) { @@ -1408,7 +1408,7 @@ func (c *ClusterClient) pipelineReadCmds( continue } - if c.opt.ReadOnly && isBadConn(err, false, node.Client.getAddr()) { + if c.opt.ReadOnly && isBadConn(ctx, err, false, node.Client.getAddr(), true) { node.MarkAsFailing() } diff --git a/pubsub.go b/pubsub.go index 72b18f49a..5c2e7e08e 100644 --- a/pubsub.go +++ b/pubsub.go @@ -150,7 +150,7 @@ func (c *PubSub) releaseConn(ctx context.Context, cn *pool.Conn, err error, allo if c.cn != cn { return } - if isBadConn(err, allowTimeout, c.opt.Addr) { + if isBadConn(ctx, err, allowTimeout, c.opt.Addr, false) { c.reconnect(ctx, err) } } diff --git a/redis.go b/redis.go index ec3ff616a..df5d58d1a 100644 --- a/redis.go +++ b/redis.go @@ -373,7 +373,7 @@ func (c *baseClient) releaseConn(ctx context.Context, cn *pool.Conn, err error) c.opt.Limiter.ReportResult(err) } - if isBadConn(err, false, c.opt.Addr) { + if isBadConn(ctx, err, false, c.opt.Addr, false) { c.connPool.Remove(ctx, cn, err) } else { c.connPool.Put(ctx, cn)