|
@@ -10,6 +10,7 @@ import (
|
|
|
|
|
|
red "github.com/go-redis/redis/v8"
|
|
red "github.com/go-redis/redis/v8"
|
|
"github.com/zeromicro/go-zero/core/breaker"
|
|
"github.com/zeromicro/go-zero/core/breaker"
|
|
|
|
+ "github.com/zeromicro/go-zero/core/errorx"
|
|
"github.com/zeromicro/go-zero/core/mapping"
|
|
"github.com/zeromicro/go-zero/core/mapping"
|
|
"github.com/zeromicro/go-zero/core/syncx"
|
|
"github.com/zeromicro/go-zero/core/syncx"
|
|
)
|
|
)
|
|
@@ -25,6 +26,7 @@ const (
|
|
blockingQueryTimeout = 5 * time.Second
|
|
blockingQueryTimeout = 5 * time.Second
|
|
readWriteTimeout = 2 * time.Second
|
|
readWriteTimeout = 2 * time.Second
|
|
defaultSlowThreshold = time.Millisecond * 100
|
|
defaultSlowThreshold = time.Millisecond * 100
|
|
|
|
+ defaultPingTimeout = time.Second
|
|
)
|
|
)
|
|
|
|
|
|
var (
|
|
var (
|
|
@@ -51,11 +53,12 @@ type (
|
|
|
|
|
|
// Redis defines a redis node/cluster. It is thread-safe.
|
|
// Redis defines a redis node/cluster. It is thread-safe.
|
|
Redis struct {
|
|
Redis struct {
|
|
- Addr string
|
|
|
|
- Type string
|
|
|
|
- Pass string
|
|
|
|
- tls bool
|
|
|
|
- brk breaker.Breaker
|
|
|
|
|
|
+ Addr string
|
|
|
|
+ Type string
|
|
|
|
+ Pass string
|
|
|
|
+ tls bool
|
|
|
|
+ brk breaker.Breaker
|
|
|
|
+ hooks []red.Hook
|
|
}
|
|
}
|
|
|
|
|
|
// RedisNode interface represents a redis node.
|
|
// RedisNode interface represents a redis node.
|
|
@@ -119,8 +122,10 @@ func NewRedis(conf RedisConf, opts ...Option) (*Redis, error) {
|
|
}
|
|
}
|
|
|
|
|
|
rds := newRedis(conf.Host, opts...)
|
|
rds := newRedis(conf.Host, opts...)
|
|
- if !rds.Ping() {
|
|
|
|
- return nil, ErrPing
|
|
|
|
|
|
+ if !conf.NonBlock {
|
|
|
|
+ if err := rds.checkConnection(conf.PingTimeout); err != nil {
|
|
|
|
+ return nil, errorx.Wrap(err, fmt.Sprintf("redis connect error, addr: %s", conf.Host))
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
return rds, nil
|
|
return rds, nil
|
|
@@ -2769,6 +2774,23 @@ func (s *Redis) ZunionstoreCtx(ctx context.Context, dest string, store *ZStore)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (s *Redis) checkConnection(pingTimeout time.Duration) error {
|
|
|
|
+ conn, err := getRedis(s)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ timeout := defaultPingTimeout
|
|
|
|
+ if pingTimeout > 0 {
|
|
|
|
+ timeout = pingTimeout
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
|
|
+ defer cancel()
|
|
|
|
+
|
|
|
|
+ return conn.Ping(ctx).Err()
|
|
|
|
+}
|
|
|
|
+
|
|
// Cluster customizes the given Redis as a cluster.
|
|
// Cluster customizes the given Redis as a cluster.
|
|
func Cluster() Option {
|
|
func Cluster() Option {
|
|
return func(r *Redis) {
|
|
return func(r *Redis) {
|
|
@@ -2795,6 +2817,14 @@ func WithTLS() Option {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// withHook customizes the given Redis with given hook, only for private use now,
|
|
|
|
+// maybe expose later.
|
|
|
|
+func withHook(hook red.Hook) Option {
|
|
|
|
+ return func(r *Redis) {
|
|
|
|
+ r.hooks = append(r.hooks, hook)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
func acceptable(err error) bool {
|
|
func acceptable(err error) bool {
|
|
return err == nil || err == red.Nil || err == context.Canceled
|
|
return err == nil || err == red.Nil || err == context.Canceled
|
|
}
|
|
}
|