From 8ad01240a494fe590a414df0c50fdb612af127e4 Mon Sep 17 00:00:00 2001 From: monkey92t Date: Tue, 27 Apr 2021 15:04:46 +0800 Subject: [PATCH 001/621] Add support for resp3 protocol (#1739) * support resp3 protocol Signed-off-by: monkey * Upgrade mod version limit go1.14 https://github.com/go-redis/redis/issues/1715#issuecomment-820685614 Signed-off-by: monkey * Remove the redundant check of ReadReply Signed-off-by: monkey * fix the problem Signed-off-by: monkey * workflows add v9 Signed-off-by: monkey * update StringStringMapCmd to MapStringStringCmd Signed-off-by: monkey --- .github/workflows/build.yml | 2 +- bench_decode_test.go | 18 +- cluster.go | 7 +- cluster_test.go | 11 +- command.go | 1518 +++++++++++++++++---------------- commands.go | 79 +- commands_test.go | 44 +- example_test.go | 6 +- go.mod | 2 +- internal/proto/reader.go | 485 +++++++---- internal/proto/reader_test.go | 66 +- internal/proto/writer.go | 4 +- pubsub_test.go | 30 - redis.go | 26 +- result.go | 4 +- ring_test.go | 3 +- sentinel.go | 67 +- sentinel_test.go | 4 +- 18 files changed, 1321 insertions(+), 1055 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f58a11ccf6..e6858a324c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ on: push: branches: [master] pull_request: - branches: [master] + branches: [master, v9] jobs: build: diff --git a/bench_decode_test.go b/bench_decode_test.go index 838280649f..b07ad4edff 100644 --- a/bench_decode_test.go +++ b/bench_decode_test.go @@ -18,14 +18,17 @@ type ClientStub struct { resp []byte } +var initHello = []byte("%1\r\n+proto\r\n:3\r\n") + func NewClientStub(resp []byte) *ClientStub { stub := &ClientStub{ resp: resp, } + stub.Cmdable = NewClient(&Options{ PoolSize: 128, Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) { - return stub.stubConn(), nil + return stub.stubConn(initHello), nil }, }) return stub @@ -40,7 +43,7 @@ func NewClusterClientStub(resp []byte) *ClientStub { PoolSize: 128, Addrs: []string{"127.0.0.1:6379"}, Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) { - return stub.stubConn(), nil + return stub.stubConn(initHello), nil }, ClusterSlots: func(_ context.Context) ([]ClusterSlot, error) { return []ClusterSlot{ @@ -65,18 +68,27 @@ func NewClusterClientStub(resp []byte) *ClientStub { return stub } -func (c *ClientStub) stubConn() *ConnStub { +func (c *ClientStub) stubConn(init []byte) *ConnStub { return &ConnStub{ + init: init, resp: c.resp, } } type ConnStub struct { + init []byte resp []byte pos int } func (c *ConnStub) Read(b []byte) (n int, err error) { + // Return conn.init() + if len(c.init) > 0 { + n = copy(b, c.init) + c.init = c.init[n:] + return n, nil + } + if len(c.resp) == 0 { return 0, io.EOF } diff --git a/cluster.go b/cluster.go index e5d49ddee7..738d50a4e5 100644 --- a/cluster.go +++ b/cluster.go @@ -1392,12 +1392,7 @@ func (c *ClusterClient) txPipelineReadQueued( return err } - switch line[0] { - case proto.ErrorReply: - return proto.ParseErrorReply(line) - case proto.ArrayReply: - // ok - default: + if line[0] != proto.RespArray { return fmt.Errorf("redis: expected '*', but got line %q", line) } diff --git a/cluster_test.go b/cluster_test.go index 3880d437d6..4c4e4d310e 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -1182,16 +1182,17 @@ var _ = Describe("ClusterClient with unavailable Cluster", func() { var client *redis.ClusterClient BeforeEach(func() { - for _, node := range cluster.clients { - err := node.ClientPause(ctx, 5*time.Second).Err() - Expect(err).NotTo(HaveOccurred()) - } - opt := redisClusterOptions() opt.ReadTimeout = 250 * time.Millisecond opt.WriteTimeout = 250 * time.Millisecond opt.MaxRedirects = 1 client = cluster.newClusterClientUnstable(opt) + Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred()) + + for _, node := range cluster.clients { + err := node.ClientPause(ctx, 5*time.Second).Err() + Expect(err).NotTo(HaveOccurred()) + } }) AfterEach(func() { diff --git a/command.go b/command.go index f10c4781aa..28fd8c13e9 100644 --- a/command.go +++ b/command.go @@ -316,31 +316,10 @@ func (cmd *Cmd) Bool() (bool, error) { } func (cmd *Cmd) readReply(rd *proto.Reader) (err error) { - cmd.val, err = rd.ReadReply(sliceParser) + cmd.val, err = rd.ReadReply() return err } -// sliceParser implements proto.MultiBulkParse. -func sliceParser(rd *proto.Reader, n int64) (interface{}, error) { - vals := make([]interface{}, n) - for i := 0; i < len(vals); i++ { - v, err := rd.ReadReply(sliceParser) - if err != nil { - if err == Nil { - vals[i] = nil - continue - } - if err, ok := err.(proto.RedisError); ok { - vals[i] = err - continue - } - return nil, err - } - vals[i] = v - } - return vals, nil -} - //------------------------------------------------------------------------------ type SliceCmd struct { @@ -392,13 +371,9 @@ func (cmd *SliceCmd) Scan(dst interface{}) error { return hscan.Scan(dst, args, cmd.val) } -func (cmd *SliceCmd) readReply(rd *proto.Reader) error { - v, err := rd.ReadArrayReply(sliceParser) - if err != nil { - return err - } - cmd.val = v.([]interface{}) - return nil +func (cmd *SliceCmd) readReply(rd *proto.Reader) (err error) { + cmd.val, err = rd.ReadSlice() + return err } //------------------------------------------------------------------------------ @@ -473,7 +448,7 @@ func (cmd *IntCmd) String() string { } func (cmd *IntCmd) readReply(rd *proto.Reader) (err error) { - cmd.val, err = rd.ReadIntReply() + cmd.val, err = rd.ReadInt() return err } @@ -509,18 +484,17 @@ func (cmd *IntSliceCmd) String() string { } func (cmd *IntSliceCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make([]int64, n) - for i := 0; i < len(cmd.val); i++ { - num, err := rd.ReadIntReply() - if err != nil { - return nil, err - } - cmd.val[i] = num + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmd.val = make([]int64, n) + for i := 0; i < len(cmd.val); i++ { + if cmd.val[i], err = rd.ReadInt(); err != nil { + return err } - return nil, nil - }) - return err + } + return nil } //------------------------------------------------------------------------------ @@ -557,7 +531,7 @@ func (cmd *DurationCmd) String() string { } func (cmd *DurationCmd) readReply(rd *proto.Reader) error { - n, err := rd.ReadIntReply() + n, err := rd.ReadInt() if err != nil { return err } @@ -604,25 +578,19 @@ func (cmd *TimeCmd) String() string { } func (cmd *TimeCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - if n != 2 { - return nil, fmt.Errorf("got %d elements, expected 2", n) - } - - sec, err := rd.ReadInt() - if err != nil { - return nil, err - } - - microsec, err := rd.ReadInt() - if err != nil { - return nil, err - } - - cmd.val = time.Unix(sec, microsec*1000) - return nil, nil - }) - return err + if err := rd.ReadFixedArrayLen(2); err != nil { + return err + } + second, err := rd.ReadInt() + if err != nil { + return err + } + microsecond, err := rd.ReadInt() + if err != nil { + return err + } + cmd.val = time.Unix(second, microsecond*1000) + return nil } //------------------------------------------------------------------------------ @@ -656,27 +624,16 @@ func (cmd *BoolCmd) String() string { return cmdString(cmd, cmd.val) } -func (cmd *BoolCmd) readReply(rd *proto.Reader) error { - v, err := rd.ReadReply(nil) +func (cmd *BoolCmd) readReply(rd *proto.Reader) (err error) { + cmd.val, err = rd.ReadBool() + // `SET key value NX` returns nil when key already exists. But // `SETNX key value` returns bool (0/1). So convert nil to bool. if err == Nil { cmd.val = false - return nil - } - if err != nil { - return err - } - switch v := v.(type) { - case int64: - cmd.val = v == 1 - return nil - case string: - cmd.val = v == "OK" - return nil - default: - return fmt.Errorf("got %T, wanted int64 or string", v) + err = nil } + return err } //------------------------------------------------------------------------------ @@ -811,7 +768,7 @@ func (cmd *FloatCmd) String() string { } func (cmd *FloatCmd) readReply(rd *proto.Reader) (err error) { - cmd.val, err = rd.ReadFloatReply() + cmd.val, err = rd.ReadFloat() return err } @@ -847,21 +804,23 @@ func (cmd *FloatSliceCmd) String() string { } func (cmd *FloatSliceCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make([]float64, n) - for i := 0; i < len(cmd.val); i++ { - switch num, err := rd.ReadFloatReply(); { - case err == Nil: - cmd.val[i] = 0 - case err != nil: - return nil, err - default: - cmd.val[i] = num - } + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + + cmd.val = make([]float64, n) + for i := 0; i < len(cmd.val); i++ { + switch num, err := rd.ReadFloat(); { + case err == Nil: + cmd.val[i] = 0 + case err != nil: + return err + default: + cmd.val[i] = num } - return nil, nil - }) - return err + } + return nil } //------------------------------------------------------------------------------ @@ -900,21 +859,111 @@ func (cmd *StringSliceCmd) ScanSlice(container interface{}) error { } func (cmd *StringSliceCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make([]string, n) - for i := 0; i < len(cmd.val); i++ { - switch s, err := rd.ReadString(); { - case err == Nil: - cmd.val[i] = "" - case err != nil: - return nil, err - default: - cmd.val[i] = s + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmd.val = make([]string, n) + for i := 0; i < len(cmd.val); i++ { + switch s, err := rd.ReadString(); { + case err == Nil: + cmd.val[i] = "" + case err != nil: + return err + default: + cmd.val[i] = s + } + } + return nil +} + +//------------------------------------------------------------------------------ + +type KeyValue struct { + Key string + Value string +} + +type KeyValueSliceCmd struct { + baseCmd + + val []KeyValue +} + +var _ Cmder = (*KeyValueSliceCmd)(nil) + +func NewKeyValueSliceCmd(ctx context.Context, args ...interface{}) *KeyValueSliceCmd { + return &KeyValueSliceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *KeyValueSliceCmd) Val() []KeyValue { + return cmd.val +} + +func (cmd *KeyValueSliceCmd) Result() ([]KeyValue, error) { + return cmd.val, cmd.err +} + +func (cmd *KeyValueSliceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +// Many commands will respond to two formats: +// 1) 1) "one" +// 2) (double) 1 +// 2) 1) "two" +// 2) (double) 2 +// OR: +// 1) "two" +// 2) (double) 2 +// 3) "one" +// 4) (double) 1 +func (cmd *KeyValueSliceCmd) readReply(rd *proto.Reader) error { // nolint:dupl + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + + // If the n is 0, can't continue reading. + if n == 0 { + cmd.val = make([]KeyValue, 0) + return nil + } + + typ, err := rd.PeekReplyType() + if err != nil { + return err + } + array := typ == proto.RespArray + + if array { + cmd.val = make([]KeyValue, n) + } else { + cmd.val = make([]KeyValue, n/2) + } + + for i := 0; i < len(cmd.val); i++ { + if array { + if err = rd.ReadFixedArrayLen(2); err != nil { + return err } } - return nil, nil - }) - return err + + if cmd.val[i].Key, err = rd.ReadString(); err != nil { + return err + } + + if cmd.val[i].Value, err = rd.ReadString(); err != nil { + return err + } + } + + return nil } //------------------------------------------------------------------------------ @@ -949,32 +998,31 @@ func (cmd *BoolSliceCmd) String() string { } func (cmd *BoolSliceCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make([]bool, n) - for i := 0; i < len(cmd.val); i++ { - n, err := rd.ReadIntReply() - if err != nil { - return nil, err - } - cmd.val[i] = n == 1 + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmd.val = make([]bool, n) + for i := 0; i < len(cmd.val); i++ { + if cmd.val[i], err = rd.ReadBool(); err != nil { + return err } - return nil, nil - }) - return err + } + return nil } //------------------------------------------------------------------------------ -type StringStringMapCmd struct { +type MapStringStringCmd struct { baseCmd val map[string]string } -var _ Cmder = (*StringStringMapCmd)(nil) +var _ Cmder = (*MapStringStringCmd)(nil) -func NewStringStringMapCmd(ctx context.Context, args ...interface{}) *StringStringMapCmd { - return &StringStringMapCmd{ +func NewMapStringStringCmd(ctx context.Context, args ...interface{}) *MapStringStringCmd { + return &MapStringStringCmd{ baseCmd: baseCmd{ ctx: ctx, args: args, @@ -982,21 +1030,21 @@ func NewStringStringMapCmd(ctx context.Context, args ...interface{}) *StringStri } } -func (cmd *StringStringMapCmd) Val() map[string]string { +func (cmd *MapStringStringCmd) Val() map[string]string { return cmd.val } -func (cmd *StringStringMapCmd) Result() (map[string]string, error) { +func (cmd *MapStringStringCmd) Result() (map[string]string, error) { return cmd.val, cmd.err } -func (cmd *StringStringMapCmd) String() string { +func (cmd *MapStringStringCmd) String() string { return cmdString(cmd, cmd.val) } // Scan scans the results from the map into a destination struct. The map keys // are matched in the Redis struct fields by the `redis:"field"` tag. -func (cmd *StringStringMapCmd) Scan(dst interface{}) error { +func (cmd *MapStringStringCmd) Scan(dst interface{}) error { if cmd.err != nil { return cmd.err } @@ -1015,25 +1063,27 @@ func (cmd *StringStringMapCmd) Scan(dst interface{}) error { return nil } -func (cmd *StringStringMapCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make(map[string]string, n/2) - for i := int64(0); i < n; i += 2 { - key, err := rd.ReadString() - if err != nil { - return nil, err - } +func (cmd *MapStringStringCmd) readReply(rd *proto.Reader) error { + n, err := rd.ReadMapLen() + if err != nil { + return err + } - value, err := rd.ReadString() - if err != nil { - return nil, err - } + cmd.val = make(map[string]string, n) + for i := 0; i < n; i++ { + key, err := rd.ReadString() + if err != nil { + return err + } - cmd.val[key] = value + value, err := rd.ReadString() + if err != nil { + return err } - return nil, nil - }) - return err + + cmd.val[key] = value + } + return nil } //------------------------------------------------------------------------------ @@ -1068,24 +1118,25 @@ func (cmd *StringIntMapCmd) String() string { } func (cmd *StringIntMapCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make(map[string]int64, n/2) - for i := int64(0); i < n; i += 2 { - key, err := rd.ReadString() - if err != nil { - return nil, err - } + n, err := rd.ReadMapLen() + if err != nil { + return err + } - n, err := rd.ReadIntReply() - if err != nil { - return nil, err - } + cmd.val = make(map[string]int64, n) + for i := 0; i < n; i++ { + key, err := rd.ReadString() + if err != nil { + return err + } - cmd.val[key] = n + nn, err := rd.ReadInt() + if err != nil { + return err } - return nil, nil - }) - return err + cmd.val[key] = nn + } + return nil } //------------------------------------------------------------------------------ @@ -1120,18 +1171,20 @@ func (cmd *StringStructMapCmd) String() string { } func (cmd *StringStructMapCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make(map[string]struct{}, n) - for i := int64(0); i < n; i++ { - key, err := rd.ReadString() - if err != nil { - return nil, err - } - cmd.val[key] = struct{}{} + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + + cmd.val = make(map[string]struct{}, n) + for i := 0; i < n; i++ { + key, err := rd.ReadString() + if err != nil { + return err } - return nil, nil - }) - return err + cmd.val[key] = struct{}{} + } + return nil } //------------------------------------------------------------------------------ @@ -1170,8 +1223,7 @@ func (cmd *XMessageSliceCmd) String() string { return cmdString(cmd, cmd.val) } -func (cmd *XMessageSliceCmd) readReply(rd *proto.Reader) error { - var err error +func (cmd *XMessageSliceCmd) readReply(rd *proto.Reader) (err error) { cmd.val, err = readXMessageSlice(rd) return err } @@ -1183,10 +1235,8 @@ func readXMessageSlice(rd *proto.Reader) ([]XMessage, error) { } msgs := make([]XMessage, n) - for i := 0; i < n; i++ { - var err error - msgs[i], err = readXMessage(rd) - if err != nil { + for i := 0; i < len(msgs); i++ { + if msgs[i], err = readXMessage(rd); err != nil { return nil, err } } @@ -1194,40 +1244,36 @@ func readXMessageSlice(rd *proto.Reader) ([]XMessage, error) { } func readXMessage(rd *proto.Reader) (XMessage, error) { - n, err := rd.ReadArrayLen() - if err != nil { + if err := rd.ReadFixedArrayLen(2); err != nil { return XMessage{}, err } - if n != 2 { - return XMessage{}, fmt.Errorf("got %d, wanted 2", n) - } id, err := rd.ReadString() if err != nil { return XMessage{}, err } - var values map[string]interface{} - - v, err := rd.ReadArrayReply(stringInterfaceMapParser) + v, err := stringInterfaceMapParser(rd) if err != nil { if err != proto.Nil { return XMessage{}, err } - } else { - values = v.(map[string]interface{}) } return XMessage{ ID: id, - Values: values, + Values: v, }, nil } -// stringInterfaceMapParser implements proto.MultiBulkParse. -func stringInterfaceMapParser(rd *proto.Reader, n int64) (interface{}, error) { - m := make(map[string]interface{}, n/2) - for i := int64(0); i < n; i += 2 { +func stringInterfaceMapParser(rd *proto.Reader) (map[string]interface{}, error) { + n, err := rd.ReadMapLen() + if err != nil { + return nil, err + } + + m := make(map[string]interface{}, n) + for i := 0; i < n; i++ { key, err := rd.ReadString() if err != nil { return nil, err @@ -1280,38 +1326,35 @@ func (cmd *XStreamSliceCmd) String() string { } func (cmd *XStreamSliceCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make([]XStream, n) - for i := 0; i < len(cmd.val); i++ { - i := i - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - if n != 2 { - return nil, fmt.Errorf("got %d, wanted 2", n) - } - - stream, err := rd.ReadString() - if err != nil { - return nil, err - } - - msgs, err := readXMessageSlice(rd) - if err != nil { - return nil, err - } + typ, err := rd.PeekReplyType() + if err != nil { + return err + } - cmd.val[i] = XStream{ - Stream: stream, - Messages: msgs, - } - return nil, nil - }) - if err != nil { - return nil, err + var n int + if typ == proto.RespMap { + n, err = rd.ReadMapLen() + } else { + n, err = rd.ReadArrayLen() + } + if err != nil { + return err + } + cmd.val = make([]XStream, n) + for i := 0; i < len(cmd.val); i++ { + if typ != proto.RespMap { + if err = rd.ReadFixedArrayLen(2); err != nil { + return err } } - return nil, nil - }) - return err + if cmd.val[i].Stream, err = rd.ReadString(); err != nil { + return err + } + if cmd.val[i].Messages, err = readXMessageSlice(rd); err != nil { + return err + } + } + return nil } //------------------------------------------------------------------------------ @@ -1352,68 +1395,45 @@ func (cmd *XPendingCmd) String() string { } func (cmd *XPendingCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - if n != 4 { - return nil, fmt.Errorf("got %d, wanted 4", n) - } + var err error + if err = rd.ReadFixedArrayLen(4); err != nil { + return err + } + cmd.val = &XPending{} - count, err := rd.ReadIntReply() - if err != nil { - return nil, err - } + if cmd.val.Count, err = rd.ReadInt(); err != nil { + return err + } - lower, err := rd.ReadString() - if err != nil && err != Nil { - return nil, err - } + if cmd.val.Lower, err = rd.ReadString(); err != nil && err != Nil { + return err + } - higher, err := rd.ReadString() - if err != nil && err != Nil { - return nil, err - } + if cmd.val.Higher, err = rd.ReadString(); err != nil && err != Nil { + return err + } - cmd.val = &XPending{ - Count: count, - Lower: lower, - Higher: higher, + n, err := rd.ReadArrayLen() + if err != nil && err != Nil { + return err + } + cmd.val.Consumers = make(map[string]int64, n) + for i := 0; i < n; i++ { + if err = rd.ReadFixedArrayLen(2); err != nil { + return err } - _, err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - for i := int64(0); i < n; i++ { - _, err = rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - if n != 2 { - return nil, fmt.Errorf("got %d, wanted 2", n) - } - - consumerName, err := rd.ReadString() - if err != nil { - return nil, err - } - consumerPending, err := rd.ReadInt() - if err != nil { - return nil, err - } - - if cmd.val.Consumers == nil { - cmd.val.Consumers = make(map[string]int64) - } - cmd.val.Consumers[consumerName] = consumerPending - - return nil, nil - }) - if err != nil { - return nil, err - } - } - return nil, nil - }) - if err != nil && err != Nil { - return nil, err + consumerName, err := rd.ReadString() + if err != nil { + return err } - - return nil, nil - }) - return err + consumerPending, err := rd.ReadInt() + if err != nil { + return err + } + cmd.val.Consumers[consumerName] = consumerPending + } + return nil } //------------------------------------------------------------------------------ @@ -1454,49 +1474,37 @@ func (cmd *XPendingExtCmd) String() string { } func (cmd *XPendingExtCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make([]XPendingExt, 0, n) - for i := int64(0); i < n; i++ { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - if n != 4 { - return nil, fmt.Errorf("got %d, wanted 4", n) - } + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmd.val = make([]XPendingExt, n) - id, err := rd.ReadString() - if err != nil { - return nil, err - } + for i := 0; i < len(cmd.val); i++ { + if err = rd.ReadFixedArrayLen(4); err != nil { + return err + } - consumer, err := rd.ReadString() - if err != nil && err != Nil { - return nil, err - } + if cmd.val[i].ID, err = rd.ReadString(); err != nil { + return err + } - idle, err := rd.ReadIntReply() - if err != nil && err != Nil { - return nil, err - } + if cmd.val[i].Consumer, err = rd.ReadString(); err != nil && err != Nil { + return err + } - retryCount, err := rd.ReadIntReply() - if err != nil && err != Nil { - return nil, err - } + idle, err := rd.ReadInt() + if err != nil && err != Nil { + return err + } + cmd.val[i].Idle = time.Duration(idle) * time.Millisecond - cmd.val = append(cmd.val, XPendingExt{ - ID: id, - Consumer: consumer, - Idle: time.Duration(idle) * time.Millisecond, - RetryCount: retryCount, - }) - return nil, nil - }) - if err != nil { - return nil, err - } + if cmd.val[i].RetryCount, err = rd.ReadInt(); err != nil && err != Nil { + return err } - return nil, nil - }) - return err + } + + return nil } //------------------------------------------------------------------------------ @@ -1540,60 +1548,37 @@ func (cmd *XInfoConsumersCmd) readReply(rd *proto.Reader) error { if err != nil { return err } - cmd.val = make([]XInfoConsumer, n) - for i := 0; i < n; i++ { - cmd.val[i], err = readXConsumerInfo(rd) - if err != nil { + for i := 0; i < len(cmd.val); i++ { + if err = rd.ReadFixedMapLen(3); err != nil { return err } - } - - return nil -} - -func readXConsumerInfo(rd *proto.Reader) (XInfoConsumer, error) { - var consumer XInfoConsumer - - n, err := rd.ReadArrayLen() - if err != nil { - return consumer, err - } - if n != 6 { - return consumer, fmt.Errorf("redis: got %d elements in XINFO CONSUMERS reply, wanted 6", n) - } - - for i := 0; i < 3; i++ { - key, err := rd.ReadString() - if err != nil { - return consumer, err - } - - val, err := rd.ReadString() - if err != nil { - return consumer, err - } - switch key { - case "name": - consumer.Name = val - case "pending": - consumer.Pending, err = strconv.ParseInt(val, 0, 64) + var key string + for f := 0; f < 3; f++ { + key, err = rd.ReadString() if err != nil { - return consumer, err + return err + } + + switch key { + case "name": + cmd.val[i].Name, err = rd.ReadString() + case "pending": + cmd.val[i].Pending, err = rd.ReadInt() + case "idle": + cmd.val[i].Idle, err = rd.ReadInt() + default: + return fmt.Errorf("redis: unexpected content %s in XINFO CONSUMERS reply", key) } - case "idle": - consumer.Idle, err = strconv.ParseInt(val, 0, 64) if err != nil { - return consumer, err + return err } - default: - return consumer, fmt.Errorf("redis: unexpected content %s in XINFO CONSUMERS reply", key) } } - return consumer, nil + return nil } //------------------------------------------------------------------------------ @@ -1638,62 +1623,39 @@ func (cmd *XInfoGroupsCmd) readReply(rd *proto.Reader) error { if err != nil { return err } - cmd.val = make([]XInfoGroup, n) - for i := 0; i < n; i++ { - cmd.val[i], err = readXGroupInfo(rd) - if err != nil { + for i := 0; i < len(cmd.val); i++ { + if err = rd.ReadFixedMapLen(4); err != nil { return err } - } - - return nil -} -func readXGroupInfo(rd *proto.Reader) (XInfoGroup, error) { - var group XInfoGroup - - n, err := rd.ReadArrayLen() - if err != nil { - return group, err - } - if n != 8 { - return group, fmt.Errorf("redis: got %d elements in XINFO GROUPS reply, wanted 8", n) - } - - for i := 0; i < 4; i++ { - key, err := rd.ReadString() - if err != nil { - return group, err - } - - val, err := rd.ReadString() - if err != nil { - return group, err - } - - switch key { - case "name": - group.Name = val - case "consumers": - group.Consumers, err = strconv.ParseInt(val, 0, 64) + var key string + for f := 0; f < 4; f++ { + key, err = rd.ReadString() if err != nil { - return group, err + return err + } + + switch key { + case "name": + cmd.val[i].Name, err = rd.ReadString() + case "consumers": + cmd.val[i].Consumers, err = rd.ReadInt() + case "pending": + cmd.val[i].Pending, err = rd.ReadInt() + case "last-delivered-id": + cmd.val[i].LastDeliveredID, err = rd.ReadString() + default: + return fmt.Errorf("redis: unexpected content %s in XINFO GROUPS reply", key) } - case "pending": - group.Pending, err = strconv.ParseInt(val, 0, 64) if err != nil { - return group, err + return err } - case "last-delivered-id": - group.LastDeliveredID = val - default: - return group, fmt.Errorf("redis: unexpected content %s in XINFO GROUPS reply", key) } } - return group, nil + return nil } //------------------------------------------------------------------------------ @@ -1737,49 +1699,40 @@ func (cmd *XInfoStreamCmd) String() string { } func (cmd *XInfoStreamCmd) readReply(rd *proto.Reader) error { - v, err := rd.ReadReply(xStreamInfoParser) - if err != nil { + if err := rd.ReadFixedMapLen(7); err != nil { return err } - cmd.val = v.(*XInfoStream) - return nil -} + cmd.val = &XInfoStream{} -func xStreamInfoParser(rd *proto.Reader, n int64) (interface{}, error) { - if n != 14 { - return nil, fmt.Errorf("redis: got %d elements in XINFO STREAM reply,"+ - "wanted 14", n) - } - var info XInfoStream for i := 0; i < 7; i++ { key, err := rd.ReadString() if err != nil { - return nil, err + return err } switch key { case "length": - info.Length, err = rd.ReadIntReply() + cmd.val.Length, err = rd.ReadInt() case "radix-tree-keys": - info.RadixTreeKeys, err = rd.ReadIntReply() + cmd.val.RadixTreeKeys, err = rd.ReadInt() case "radix-tree-nodes": - info.RadixTreeNodes, err = rd.ReadIntReply() + cmd.val.RadixTreeNodes, err = rd.ReadInt() case "groups": - info.Groups, err = rd.ReadIntReply() + cmd.val.Groups, err = rd.ReadInt() case "last-generated-id": - info.LastGeneratedID, err = rd.ReadString() + cmd.val.LastGeneratedID, err = rd.ReadString() case "first-entry": - info.FirstEntry, err = readXMessage(rd) + cmd.val.FirstEntry, err = readXMessage(rd) case "last-entry": - info.LastEntry, err = readXMessage(rd) + cmd.val.LastEntry, err = readXMessage(rd) default: - return nil, fmt.Errorf("redis: unexpected content %s "+ + return fmt.Errorf("redis: unexpected content %s "+ "in XINFO STREAM reply", key) } if err != nil { - return nil, err + return err } } - return &info, nil + return nil } //------------------------------------------------------------------------------ @@ -1813,28 +1766,47 @@ func (cmd *ZSliceCmd) String() string { return cmdString(cmd, cmd.val) } -func (cmd *ZSliceCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { +func (cmd *ZSliceCmd) readReply(rd *proto.Reader) error { // nolint:dupl + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + + // If the n is 0, can't continue reading. + if n == 0 { + cmd.val = make([]Z, 0) + return nil + } + + typ, err := rd.PeekReplyType() + if err != nil { + return err + } + array := typ == proto.RespArray + + if array { + cmd.val = make([]Z, n) + } else { cmd.val = make([]Z, n/2) - for i := 0; i < len(cmd.val); i++ { - member, err := rd.ReadString() - if err != nil { - return nil, err - } + } - score, err := rd.ReadFloatReply() - if err != nil { - return nil, err + for i := 0; i < len(cmd.val); i++ { + if array { + if err = rd.ReadFixedArrayLen(2); err != nil { + return err } + } - cmd.val[i] = Z{ - Member: member, - Score: score, - } + if cmd.val[i].Member, err = rd.ReadString(); err != nil { + return err } - return nil, nil - }) - return err + + if cmd.val[i].Score, err = rd.ReadFloat(); err != nil { + return err + } + } + + return nil } //------------------------------------------------------------------------------ @@ -1868,33 +1840,23 @@ func (cmd *ZWithKeyCmd) String() string { return cmdString(cmd, cmd.val) } -func (cmd *ZWithKeyCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - if n != 3 { - return nil, fmt.Errorf("got %d elements, expected 3", n) - } - - cmd.val = &ZWithKey{} - var err error - - cmd.val.Key, err = rd.ReadString() - if err != nil { - return nil, err - } - - cmd.val.Member, err = rd.ReadString() - if err != nil { - return nil, err - } +func (cmd *ZWithKeyCmd) readReply(rd *proto.Reader) (err error) { + if err = rd.ReadFixedArrayLen(3); err != nil { + return err + } + cmd.val = &ZWithKey{} - cmd.val.Score, err = rd.ReadFloatReply() - if err != nil { - return nil, err - } + if cmd.val.Key, err = rd.ReadString(); err != nil { + return err + } + if cmd.val.Member, err = rd.ReadString(); err != nil { + return err + } + if cmd.val.Score, err = rd.ReadFloat(); err != nil { + return err + } - return nil, nil - }) - return err + return nil } //------------------------------------------------------------------------------ @@ -1932,9 +1894,29 @@ func (cmd *ScanCmd) String() string { return cmdString(cmd, cmd.page) } -func (cmd *ScanCmd) readReply(rd *proto.Reader) (err error) { - cmd.page, cmd.cursor, err = rd.ReadScanReply() - return err +func (cmd *ScanCmd) readReply(rd *proto.Reader) error { + if err := rd.ReadFixedArrayLen(2); err != nil { + return err + } + + cursor, err := rd.ReadInt() + if err != nil { + return err + } + cmd.cursor = uint64(cursor) + + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmd.page = make([]string, n) + + for i := 0; i < len(cmd.page); i++ { + if cmd.page[i], err = rd.ReadString(); err != nil { + return err + } + } + return nil } // Iterator creates a new ScanIterator. @@ -1987,69 +1969,70 @@ func (cmd *ClusterSlotsCmd) String() string { } func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make([]ClusterSlot, n) - for i := 0; i < len(cmd.val); i++ { - n, err := rd.ReadArrayLen() + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmd.val = make([]ClusterSlot, n) + + for i := 0; i < len(cmd.val); i++ { + n, err = rd.ReadArrayLen() + if err != nil { + return err + } + if n < 2 { + return fmt.Errorf("redis: got %d elements in cluster info, expected at least 2", n) + } + + start, err := rd.ReadInt() + if err != nil { + return err + } + + end, err := rd.ReadInt() + if err != nil { + return err + } + + // subtract start and end. + nodes := make([]ClusterNode, n-2) + for j := 0; j < len(nodes); j++ { + nn, err := rd.ReadArrayLen() if err != nil { - return nil, err + return err } - if n < 2 { - err := fmt.Errorf("redis: got %d elements in cluster info, expected at least 2", n) - return nil, err + if nn != 2 && nn != 3 { + return fmt.Errorf("got %d elements in cluster info address, expected 2 or 3", nn) } - start, err := rd.ReadIntReply() + ip, err := rd.ReadString() if err != nil { - return nil, err + return err } - end, err := rd.ReadIntReply() + port, err := rd.ReadString() if err != nil { - return nil, err + return err } - nodes := make([]ClusterNode, n-2) - for j := 0; j < len(nodes); j++ { - n, err := rd.ReadArrayLen() - if err != nil { - return nil, err - } - if n != 2 && n != 3 { - err := fmt.Errorf("got %d elements in cluster info address, expected 2 or 3", n) - return nil, err - } - - ip, err := rd.ReadString() - if err != nil { - return nil, err - } + nodes[j].Addr = net.JoinHostPort(ip, port) - port, err := rd.ReadString() + if nn == 3 { + id, err := rd.ReadString() if err != nil { - return nil, err - } - - nodes[j].Addr = net.JoinHostPort(ip, port) - - if n == 3 { - id, err := rd.ReadString() - if err != nil { - return nil, err - } - nodes[j].ID = id + return err } - } - - cmd.val[i] = ClusterSlot{ - Start: int(start), - End: int(end), - Nodes: nodes, + nodes[j].ID = id } } - return nil, nil - }) - return err + cmd.val[i] = ClusterSlot{ + Start: int(start), + End: int(end), + Nodes: nodes, + } + } + + return nil } //------------------------------------------------------------------------------ @@ -2074,6 +2057,9 @@ type GeoRadiusQuery struct { Sort string Store string StoreDist string + + // WithCoord+WithDist+WithGeoHash + withLen int } type GeoLocationCmd struct { @@ -2104,12 +2090,15 @@ func geoLocationArgs(q *GeoRadiusQuery, args ...interface{}) []interface{} { } if q.WithCoord { args = append(args, "withcoord") + q.withLen++ } if q.WithDist { args = append(args, "withdist") + q.withLen++ } if q.WithGeoHash { args = append(args, "withhash") + q.withLen++ } if q.Count > 0 { args = append(args, "count", q.Count) @@ -2141,80 +2130,53 @@ func (cmd *GeoLocationCmd) String() string { } func (cmd *GeoLocationCmd) readReply(rd *proto.Reader) error { - v, err := rd.ReadArrayReply(newGeoLocationSliceParser(cmd.q)) + n, err := rd.ReadArrayLen() if err != nil { return err } - cmd.locations = v.([]GeoLocation) - return nil -} + cmd.locations = make([]GeoLocation, n) -func newGeoLocationSliceParser(q *GeoRadiusQuery) proto.MultiBulkParse { - return func(rd *proto.Reader, n int64) (interface{}, error) { - locs := make([]GeoLocation, 0, n) - for i := int64(0); i < n; i++ { - v, err := rd.ReadReply(newGeoLocationParser(q)) - if err != nil { - return nil, err - } - switch vv := v.(type) { - case string: - locs = append(locs, GeoLocation{ - Name: vv, - }) - case *GeoLocation: - // TODO: avoid copying - locs = append(locs, *vv) - default: - return nil, fmt.Errorf("got %T, expected string or *GeoLocation", v) + for i := 0; i < len(cmd.locations); i++ { + // only name + if cmd.q.withLen == 0 { + if cmd.locations[i].Name, err = rd.ReadString(); err != nil { + return err } + continue } - return locs, nil - } -} -func newGeoLocationParser(q *GeoRadiusQuery) proto.MultiBulkParse { - return func(rd *proto.Reader, n int64) (interface{}, error) { - var loc GeoLocation - var err error + // +name + if err = rd.ReadFixedArrayLen(cmd.q.withLen + 1); err != nil { + return err + } - loc.Name, err = rd.ReadString() - if err != nil { - return nil, err + if cmd.locations[i].Name, err = rd.ReadString(); err != nil { + return err } - if q.WithDist { - loc.Dist, err = rd.ReadFloatReply() - if err != nil { - return nil, err + if cmd.q.WithDist { + if cmd.locations[i].Dist, err = rd.ReadFloat(); err != nil { + return err } } - if q.WithGeoHash { - loc.GeoHash, err = rd.ReadIntReply() - if err != nil { - return nil, err + if cmd.q.WithGeoHash { + if cmd.locations[i].GeoHash, err = rd.ReadInt(); err != nil { + return err } } - if q.WithCoord { - n, err := rd.ReadArrayLen() - if err != nil { - return nil, err + if cmd.q.WithCoord { + if err = rd.ReadFixedArrayLen(2); err != nil { + return err } - if n != 2 { - return nil, fmt.Errorf("got %d coordinates, expected 2", n) + if cmd.locations[i].Longitude, err = rd.ReadFloat(); err != nil { + return err } - - loc.Longitude, err = rd.ReadFloatReply() - if err != nil { - return nil, err - } - loc.Latitude, err = rd.ReadFloatReply() - if err != nil { - return nil, err + if cmd.locations[i].Latitude, err = rd.ReadFloat(); err != nil { + return err } } - - return &loc, nil } + + return nil } //------------------------------------------------------------------------------ @@ -2253,38 +2215,38 @@ func (cmd *GeoPosCmd) String() string { } func (cmd *GeoPosCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make([]*GeoPos, n) - for i := 0; i < len(cmd.val); i++ { - i := i - _, err := rd.ReadReply(func(rd *proto.Reader, n int64) (interface{}, error) { - longitude, err := rd.ReadFloatReply() - if err != nil { - return nil, err - } - - latitude, err := rd.ReadFloatReply() - if err != nil { - return nil, err - } + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmd.val = make([]*GeoPos, n) - cmd.val[i] = &GeoPos{ - Longitude: longitude, - Latitude: latitude, - } - return nil, nil - }) - if err != nil { - if err == Nil { - cmd.val[i] = nil - continue - } - return nil, err + for i := 0; i < len(cmd.val); i++ { + err = rd.ReadFixedArrayLen(2) + if err != nil { + if err == Nil { + cmd.val[i] = nil + continue } + return err } - return nil, nil - }) - return err + + longitude, err := rd.ReadFloat() + if err != nil { + return err + } + latitude, err := rd.ReadFloat() + if err != nil { + return err + } + + cmd.val[i] = &GeoPos{ + Longitude: longitude, + Latitude: latitude, + } + } + + return nil } //------------------------------------------------------------------------------ @@ -2330,112 +2292,94 @@ func (cmd *CommandsInfoCmd) String() string { } func (cmd *CommandsInfoCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make(map[string]*CommandInfo, n) - for i := int64(0); i < n; i++ { - v, err := rd.ReadReply(commandInfoParser) - if err != nil { - return nil, err - } - vv := v.(*CommandInfo) - cmd.val[vv.Name] = vv - } - return nil, nil - }) - return err -} - -func commandInfoParser(rd *proto.Reader, n int64) (interface{}, error) { const numArgRedis5 = 6 const numArgRedis6 = 7 - switch n { - case numArgRedis5, numArgRedis6: - // continue - default: - return nil, fmt.Errorf("redis: got %d elements in COMMAND reply, wanted 7", n) + n, err := rd.ReadArrayLen() + if err != nil { + return err } + cmd.val = make(map[string]*CommandInfo, n) - var cmd CommandInfo - var err error + for i := 0; i < n; i++ { + nn, err := rd.ReadArrayLen() + if err != nil { + return err + } + if nn != numArgRedis5 && nn != numArgRedis6 { + return fmt.Errorf("redis: got %d elements in COMMAND reply, wanted 6/7", nn) + } - cmd.Name, err = rd.ReadString() - if err != nil { - return nil, err - } + cmdInfo := &CommandInfo{} + if cmdInfo.Name, err = rd.ReadString(); err != nil { + return err + } - arity, err := rd.ReadIntReply() - if err != nil { - return nil, err - } - cmd.Arity = int8(arity) + arity, err := rd.ReadInt() + if err != nil { + return err + } + cmdInfo.Arity = int8(arity) - _, err = rd.ReadReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.Flags = make([]string, n) - for i := 0; i < len(cmd.Flags); i++ { + flagLen, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmdInfo.Flags = make([]string, flagLen) + for f := 0; f < len(cmdInfo.Flags); f++ { switch s, err := rd.ReadString(); { case err == Nil: - cmd.Flags[i] = "" + cmdInfo.Flags[f] = "" case err != nil: - return nil, err + return err default: - cmd.Flags[i] = s + if !cmdInfo.ReadOnly && s == "readonly" { + cmdInfo.ReadOnly = true + } + cmdInfo.Flags[f] = s } } - return nil, nil - }) - if err != nil { - return nil, err - } - firstKeyPos, err := rd.ReadIntReply() - if err != nil { - return nil, err - } - cmd.FirstKeyPos = int8(firstKeyPos) - - lastKeyPos, err := rd.ReadIntReply() - if err != nil { - return nil, err - } - cmd.LastKeyPos = int8(lastKeyPos) - - stepCount, err := rd.ReadIntReply() - if err != nil { - return nil, err - } - cmd.StepCount = int8(stepCount) + firstKeyPos, err := rd.ReadInt() + if err != nil { + return err + } + cmdInfo.FirstKeyPos = int8(firstKeyPos) - for _, flag := range cmd.Flags { - if flag == "readonly" { - cmd.ReadOnly = true - break + lastKeyPos, err := rd.ReadInt() + if err != nil { + return err } - } + cmdInfo.LastKeyPos = int8(lastKeyPos) - if n == numArgRedis5 { - return &cmd, nil - } + stepCount, err := rd.ReadInt() + if err != nil { + return err + } + cmdInfo.StepCount = int8(stepCount) - _, err = rd.ReadReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.ACLFlags = make([]string, n) - for i := 0; i < len(cmd.ACLFlags); i++ { - switch s, err := rd.ReadString(); { - case err == Nil: - cmd.ACLFlags[i] = "" - case err != nil: - return nil, err - default: - cmd.ACLFlags[i] = s + if nn == numArgRedis6 { + aclFlagLen, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmdInfo.ACLFlags = make([]string, aclFlagLen) + for f := 0; f < len(cmdInfo.ACLFlags); f++ { + switch s, err := rd.ReadString(); { + case err == Nil: + cmdInfo.ACLFlags[f] = "" + case err != nil: + return err + default: + cmdInfo.ACLFlags[f] = s + } } } - return nil, nil - }) - if err != nil { - return nil, err + + cmd.val[cmdInfo.Name] = cmdInfo } - return &cmd, nil + return nil } //------------------------------------------------------------------------------ @@ -2517,75 +2461,185 @@ func (cmd *SlowLogCmd) String() string { } func (cmd *SlowLogCmd) readReply(rd *proto.Reader) error { - _, err := rd.ReadArrayReply(func(rd *proto.Reader, n int64) (interface{}, error) { - cmd.val = make([]SlowLog, n) - for i := 0; i < len(cmd.val); i++ { - n, err := rd.ReadArrayLen() - if err != nil { - return nil, err - } - if n < 4 { - err := fmt.Errorf("redis: got %d elements in slowlog get, expected at least 4", n) - return nil, err - } + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + cmd.val = make([]SlowLog, n) + + for i := 0; i < len(cmd.val); i++ { + nn, err := rd.ReadArrayLen() + if err != nil { + return err + } + if nn < 4 { + return fmt.Errorf("redis: got %d elements in slowlog get, expected at least 4", nn) + } + + if cmd.val[i].ID, err = rd.ReadInt(); err != nil { + return err + } + + createdAt, err := rd.ReadInt() + if err != nil { + return err + } + cmd.val[i].Time = time.Unix(createdAt, 0) + + costs, err := rd.ReadInt() + if err != nil { + return err + } + cmd.val[i].Duration = time.Duration(costs) * time.Microsecond - id, err := rd.ReadIntReply() + cmdLen, err := rd.ReadArrayLen() + if err != nil { + return err + } + if cmdLen < 1 { + return fmt.Errorf("redis: got %d elements commands reply in slowlog get, expected at least 1", cmdLen) + } + + cmd.val[i].Args = make([]string, cmdLen) + for f := 0; f < len(cmd.val[i].Args); f++ { + cmd.val[i].Args[f], err = rd.ReadString() if err != nil { - return nil, err + return err } + } - createdAt, err := rd.ReadIntReply() - if err != nil { - return nil, err + if nn >= 5 { + if cmd.val[i].ClientAddr, err = rd.ReadString(); err != nil { + return err } - createdAtTime := time.Unix(createdAt, 0) + } - costs, err := rd.ReadIntReply() - if err != nil { - return nil, err + if nn >= 6 { + if cmd.val[i].ClientName, err = rd.ReadString(); err != nil { + return err } - costsDuration := time.Duration(costs) * time.Microsecond + } + } - cmdLen, err := rd.ReadArrayLen() - if err != nil { - return nil, err + return nil +} + +//----------------------------------------------------------------------- + +type MapStringInterfaceCmd struct { + baseCmd + + val map[string]interface{} +} + +var _ Cmder = (*MapStringInterfaceCmd)(nil) + +func NewMapStringInterfaceCmd(ctx context.Context, args ...interface{}) *MapStringInterfaceCmd { + return &MapStringInterfaceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *MapStringInterfaceCmd) Val() map[string]interface{} { + return cmd.val +} + +func (cmd *MapStringInterfaceCmd) Result() (map[string]interface{}, error) { + return cmd.Val(), cmd.Err() +} + +func (cmd *MapStringInterfaceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *MapStringInterfaceCmd) readReply(rd *proto.Reader) error { + n, err := rd.ReadMapLen() + if err != nil { + return err + } + + cmd.val = make(map[string]interface{}, n) + for i := 0; i < n; i++ { + k, err := rd.ReadString() + if err != nil { + return err + } + v, err := rd.ReadReply() + if err != nil { + if err == Nil { + cmd.val[k] = Nil + continue } - if cmdLen < 1 { - err := fmt.Errorf("redis: got %d elements commands reply in slowlog get, expected at least 1", cmdLen) - return nil, err + if err, ok := err.(proto.RedisError); ok { + cmd.val[k] = err + continue } + return err + } + cmd.val[k] = v + } + return nil +} - cmdString := make([]string, cmdLen) - for i := 0; i < cmdLen; i++ { - cmdString[i], err = rd.ReadString() - if err != nil { - return nil, err - } - } +//----------------------------------------------------------------------- - var address, name string - for i := 4; i < n; i++ { - str, err := rd.ReadString() - if err != nil { - return nil, err - } - if i == 4 { - address = str - } else if i == 5 { - name = str - } +type MapStringStringSliceCmd struct { + baseCmd + + val []map[string]string +} + +var _ Cmder = (*MapStringStringSliceCmd)(nil) + +func NewMapStringStringSliceCmd(ctx context.Context, args ...interface{}) *MapStringStringSliceCmd { + return &MapStringStringSliceCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *MapStringStringSliceCmd) Val() []map[string]string { + return cmd.val +} + +func (cmd *MapStringStringSliceCmd) Result() ([]map[string]string, error) { + return cmd.Val(), cmd.Err() +} + +func (cmd *MapStringStringSliceCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *MapStringStringSliceCmd) readReply(rd *proto.Reader) error { + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + + cmd.val = make([]map[string]string, n) + for i := 0; i < n; i++ { + nn, err := rd.ReadMapLen() + if err != nil { + return err + } + cmd.val[i] = make(map[string]string, nn) + for f := 0; f < nn; f++ { + k, err := rd.ReadString() + if err != nil { + return err } - cmd.val[i] = SlowLog{ - ID: id, - Time: createdAtTime, - Duration: costsDuration, - Args: cmdString, - ClientAddr: address, - ClientName: name, + v, err := rd.ReadString() + if err != nil { + return err } + cmd.val[i][k] = v } - return nil, nil - }) - return err + } + return nil } diff --git a/commands.go b/commands.go index 37746334df..65ca464004 100644 --- a/commands.go +++ b/commands.go @@ -158,7 +158,7 @@ type Cmdable interface { HDel(ctx context.Context, key string, fields ...string) *IntCmd HExists(ctx context.Context, key, field string) *BoolCmd HGet(ctx context.Context, key, field string) *StringCmd - HGetAll(ctx context.Context, key string) *StringStringMapCmd + HGetAll(ctx context.Context, key string) *MapStringStringCmd HIncrBy(ctx context.Context, key, field string, incr int64) *IntCmd HIncrByFloat(ctx context.Context, key, field string, incr float64) *FloatCmd HKeys(ctx context.Context, key string) *StringSliceCmd @@ -168,7 +168,8 @@ type Cmdable interface { HMSet(ctx context.Context, key string, values ...interface{}) *BoolCmd HSetNX(ctx context.Context, key, field string, value interface{}) *BoolCmd HVals(ctx context.Context, key string) *StringSliceCmd - HRandField(ctx context.Context, key string, count int, withValues bool) *StringSliceCmd + HRandField(ctx context.Context, key string, count int) *StringSliceCmd + HRandFieldWithValues(ctx context.Context, key string, count int) *KeyValueSliceCmd BLPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd BRPop(ctx context.Context, timeout time.Duration, keys ...string) *StringSliceCmd @@ -274,7 +275,8 @@ type Cmdable interface { ZRevRank(ctx context.Context, key, member string) *IntCmd ZScore(ctx context.Context, key, member string) *FloatCmd ZUnionStore(ctx context.Context, dest string, store *ZStore) *IntCmd - ZRandMember(ctx context.Context, key string, count int, withScores bool) *StringSliceCmd + ZRandMember(ctx context.Context, key string, count int) *StringSliceCmd + ZRandMemberWithScores(ctx context.Context, key string, count int) *ZSliceCmd PFAdd(ctx context.Context, key string, els ...interface{}) *IntCmd PFCount(ctx context.Context, keys ...string) *IntCmd @@ -287,7 +289,7 @@ type Cmdable interface { ClientList(ctx context.Context) *StringCmd ClientPause(ctx context.Context, dur time.Duration) *BoolCmd ClientID(ctx context.Context) *IntCmd - ConfigGet(ctx context.Context, parameter string) *SliceCmd + ConfigGet(ctx context.Context, parameter string) *MapStringStringCmd ConfigResetStat(ctx context.Context) *StatusCmd ConfigSet(ctx context.Context, parameter, value string) *StatusCmd ConfigRewrite(ctx context.Context) *StatusCmd @@ -358,6 +360,7 @@ type StatefulCmdable interface { Select(ctx context.Context, index int) *StatusCmd SwapDB(ctx context.Context, index1, index2 int) *StatusCmd ClientSetName(ctx context.Context, name string) *BoolCmd + Hello(ctx context.Context, ver int, username, password, clientName string) *MapStringInterfaceCmd } var ( @@ -413,6 +416,26 @@ func (c statefulCmdable) ClientSetName(ctx context.Context, name string) *BoolCm return cmd } +// Set the resp protocol used. +func (c statefulCmdable) Hello(ctx context.Context, + ver int, username, password, clientName string) *MapStringInterfaceCmd { + args := make([]interface{}, 0, 7) + args = append(args, "hello", ver) + if password != "" { + if username != "" { + args = append(args, "auth", username, password) + } else { + args = append(args, "auth", "default", password) + } + } + if clientName != "" { + args = append(args, "setname", clientName) + } + cmd := NewMapStringInterfaceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + //------------------------------------------------------------------------------ func (c cmdable) Command(ctx context.Context) *CommandsInfoCmd { @@ -440,7 +463,7 @@ func (c cmdable) Ping(ctx context.Context) *StatusCmd { return cmd } -func (c cmdable) Quit(ctx context.Context) *StatusCmd { +func (c cmdable) Quit(_ context.Context) *StatusCmd { panic("not implemented") } @@ -1138,8 +1161,8 @@ func (c cmdable) HGet(ctx context.Context, key, field string) *StringCmd { return cmd } -func (c cmdable) HGetAll(ctx context.Context, key string) *StringStringMapCmd { - cmd := NewStringStringMapCmd(ctx, "hgetall", key) +func (c cmdable) HGetAll(ctx context.Context, key string) *MapStringStringCmd { + cmd := NewMapStringStringCmd(ctx, "hgetall", key) _ = c(ctx, cmd) return cmd } @@ -1222,16 +1245,15 @@ func (c cmdable) HVals(ctx context.Context, key string) *StringSliceCmd { } // redis-server version >= 6.2.0. -func (c cmdable) HRandField(ctx context.Context, key string, count int, withValues bool) *StringSliceCmd { - args := make([]interface{}, 0, 4) - - // Although count=0 is meaningless, redis accepts count=0. - args = append(args, "hrandfield", key, count) - if withValues { - args = append(args, "withvalues") - } +func (c cmdable) HRandField(ctx context.Context, key string, count int) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "hrandfield", key, count) + _ = c(ctx, cmd) + return cmd +} - cmd := NewStringSliceCmd(ctx, args...) +// redis-server version >= 6.2.0. +func (c cmdable) HRandFieldWithValues(ctx context.Context, key string, count int) *KeyValueSliceCmd { + cmd := NewKeyValueSliceCmd(ctx, "hrandfield", key, count, "withvalues") _ = c(ctx, cmd) return cmd } @@ -2316,17 +2338,16 @@ func (c cmdable) ZUnionStore(ctx context.Context, dest string, store *ZStore) *I return cmd } -// redis-server version >= 6.2.0. -func (c cmdable) ZRandMember(ctx context.Context, key string, count int, withScores bool) *StringSliceCmd { - args := make([]interface{}, 0, 4) - - // Although count=0 is meaningless, redis accepts count=0. - args = append(args, "zrandmember", key, count) - if withScores { - args = append(args, "withscores") - } +// ZRandMember redis-server version >= 6.2.0. +func (c cmdable) ZRandMember(ctx context.Context, key string, count int) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "zrandmember", key, count) + _ = c(ctx, cmd) + return cmd +} - cmd := NewStringSliceCmd(ctx, args...) +// ZRandMemberWithScores redis-server version >= 6.2.0. +func (c cmdable) ZRandMemberWithScores(ctx context.Context, key string, count int) *ZSliceCmd { + cmd := NewZSliceCmd(ctx, "zrandmember", key, count, "withscores") _ = c(ctx, cmd) return cmd } @@ -2431,8 +2452,8 @@ func (c cmdable) ClientUnblockWithError(ctx context.Context, id int64) *IntCmd { return cmd } -func (c cmdable) ConfigGet(ctx context.Context, parameter string) *SliceCmd { - cmd := NewSliceCmd(ctx, "config", "get", parameter) +func (c cmdable) ConfigGet(ctx context.Context, parameter string) *MapStringStringCmd { + cmd := NewMapStringStringCmd(ctx, "config", "get", parameter) _ = c(ctx, cmd) return cmd } @@ -2553,7 +2574,7 @@ func (c cmdable) SlowLogGet(ctx context.Context, num int64) *SlowLogCmd { return cmd } -func (c cmdable) Sync(ctx context.Context) { +func (c cmdable) Sync(_ context.Context) { panic("not implemented") } diff --git a/commands_test.go b/commands_test.go index e927c58ddd..144958746f 100644 --- a/commands_test.go +++ b/commands_test.go @@ -47,6 +47,17 @@ var _ = Describe("Commands", func() { Expect(stats.IdleConns).To(Equal(uint32(1))) }) + It("should hello", func() { + cmds, err := client.Pipelined(ctx, func(pipe redis.Pipeliner) error { + pipe.Hello(ctx, 3, "", "", "") + return nil + }) + Expect(err).NotTo(HaveOccurred()) + m, err := cmds[0].(*redis.MapStringInterfaceCmd).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(m["proto"]).To(Equal(int64(3))) + }) + It("should Echo", func() { pipe := client.Pipeline() echo := pipe.Echo(ctx, "hello") @@ -182,10 +193,11 @@ var _ = Describe("Commands", func() { It("should ConfigSet", func() { configGet := client.ConfigGet(ctx, "maxmemory") Expect(configGet.Err()).NotTo(HaveOccurred()) - Expect(configGet.Val()).To(HaveLen(2)) - Expect(configGet.Val()[0]).To(Equal("maxmemory")) + Expect(configGet.Val()).To(HaveLen(1)) + _, ok := configGet.Val()["maxmemory"] + Expect(ok).To(BeTrue()) - configSet := client.ConfigSet(ctx, "maxmemory", configGet.Val()[1].(string)) + configSet := client.ConfigSet(ctx, "maxmemory", configGet.Val()["maxmemory"]) Expect(configSet.Err()).NotTo(HaveOccurred()) Expect(configSet.Val()).To(Equal("OK")) }) @@ -1839,18 +1851,20 @@ var _ = Describe("Commands", func() { err = client.HSet(ctx, "hash", "key2", "hello2").Err() Expect(err).NotTo(HaveOccurred()) - v := client.HRandField(ctx, "hash", 1, false) + v := client.HRandField(ctx, "hash", 1) Expect(v.Err()).NotTo(HaveOccurred()) Expect(v.Val()).To(Or(Equal([]string{"key1"}), Equal([]string{"key2"}))) - v = client.HRandField(ctx, "hash", 0, false) + v = client.HRandField(ctx, "hash", 0) Expect(v.Err()).NotTo(HaveOccurred()) Expect(v.Val()).To(HaveLen(0)) - var slice []string - err = client.HRandField(ctx, "hash", 1, true).ScanSlice(&slice) + kv, err := client.HRandFieldWithValues(ctx, "hash", 1).Result() Expect(err).NotTo(HaveOccurred()) - Expect(slice).To(Or(Equal([]string{"key1", "hello1"}), Equal([]string{"key2", "hello2"}))) + Expect(kv).To(Or( + Equal([]redis.KeyValue{{Key: "key1", Value: "hello1"}}), + Equal([]redis.KeyValue{{Key: "key2", Value: "hello2"}}), + )) }) }) @@ -3919,18 +3933,20 @@ var _ = Describe("Commands", func() { err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - v := client.ZRandMember(ctx, "zset", 1, false) + v := client.ZRandMember(ctx, "zset", 1) Expect(v.Err()).NotTo(HaveOccurred()) Expect(v.Val()).To(Or(Equal([]string{"one"}), Equal([]string{"two"}))) - v = client.ZRandMember(ctx, "zset", 0, false) + v = client.ZRandMember(ctx, "zset", 0) Expect(v.Err()).NotTo(HaveOccurred()) Expect(v.Val()).To(HaveLen(0)) - var slice []string - err = client.ZRandMember(ctx, "zset", 1, true).ScanSlice(&slice) + kv, err := client.ZRandMemberWithScores(ctx, "zset", 1).Result() Expect(err).NotTo(HaveOccurred()) - Expect(slice).To(Or(Equal([]string{"one", "1"}), Equal([]string{"two", "2"}))) + Expect(kv).To(Or( + Equal([]redis.Z{{Member: "one", Score: 1}}), + Equal([]redis.Z{{Member: "two", Score: 2}}), + )) }) }) @@ -4675,7 +4691,7 @@ var _ = Describe("Commands", func() { old := client.ConfigGet(ctx, key).Val() client.ConfigSet(ctx, key, "0") - defer client.ConfigSet(ctx, key, old[1].(string)) + defer client.ConfigSet(ctx, key, old[key]) err := rdb.Do(ctx, "slowlog", "reset").Err() Expect(err).NotTo(HaveOccurred()) diff --git a/example_test.go b/example_test.go index 7d9f7405e5..73b2f2d6e8 100644 --- a/example_test.go +++ b/example_test.go @@ -276,9 +276,9 @@ func ExampleClient_ScanType() { // Output: found 33 keys } -// ExampleStringStringMapCmd_Scan shows how to scan the results of a map fetch +// ExampleMapStringStringCmd_Scan shows how to scan the results of a map fetch // into a struct. -func ExampleStringStringMapCmd_Scan() { +func ExampleMapStringStringCmd_Scan() { rdb.FlushDB(ctx) err := rdb.HMSet(ctx, "map", "name", "hello", @@ -615,7 +615,7 @@ func ExampleClient_SlowLogGet() { old := rdb.ConfigGet(ctx, key).Val() rdb.ConfigSet(ctx, key, "0") - defer rdb.ConfigSet(ctx, key, old[1].(string)) + defer rdb.ConfigSet(ctx, key, old[key]) if err := rdb.Do(ctx, "slowlog", "reset").Err(); err != nil { panic(err) diff --git a/go.mod b/go.mod index 938768f2b8..1d3dfe1b83 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/go-redis/redis/v8 -go 1.13 +go 1.14 require ( github.com/cespare/xxhash/v2 v2.1.1 diff --git a/internal/proto/reader.go b/internal/proto/reader.go index 0ab8c9d2fc..410e46664e 100644 --- a/internal/proto/reader.go +++ b/internal/proto/reader.go @@ -2,20 +2,39 @@ package proto import ( "bufio" + "errors" "fmt" "io" + "math" + "math/big" + "strconv" "github.com/go-redis/redis/v8/internal/util" ) const ( - ErrorReply = '-' - StatusReply = '+' - IntReply = ':' - StringReply = '$' - ArrayReply = '*' + RespStatus = '+' // +\r\n + RespError = '-' // -\r\n + RespString = '$' // $\r\n\r\n + RespInt = ':' // :\r\n + RespNil = '_' // _\r\n + RespFloat = ',' // ,\r\n (golang float) + RespBool = '#' // true: #t\r\n false: #f\r\n + RespBlobError = '!' // !\r\n\r\n + RespVerbatim = '=' // =\r\nFORMAT:\r\n + RespBigInt = '(' // (\r\n + RespArray = '*' // *\r\n... (same as resp2) + RespMap = '%' // %\r\n(key)\r\n(value)\r\n... (golang map) + RespSet = '~' // ~\r\n... (same as Array) + RespAttr = '|' // |\r\n(key)\r\n(value)\r\n... + command reply + RespPush = '>' // >\r\n... (same as Array) ) +// Not used temporarily. +// Redis has not used these two data types for the time being, and will implement them later. +// Streamed = "EOF:" +// StreamedAggregated = '?' + //------------------------------------------------------------------------------ const Nil = RedisError("redis: nil") @@ -26,19 +45,19 @@ func (e RedisError) Error() string { return string(e) } func (RedisError) RedisError() {} -//------------------------------------------------------------------------------ +func ParseErrorReply(line []byte) error { + return RedisError(line[1:]) +} -type MultiBulkParse func(*Reader, int64) (interface{}, error) +//------------------------------------------------------------------------------ type Reader struct { - rd *bufio.Reader - _buf []byte + rd *bufio.Reader } func NewReader(rd io.Reader) *Reader { return &Reader{ - rd: bufio.NewReader(rd), - _buf: make([]byte, 64), + rd: bufio.NewReader(rd), } } @@ -54,14 +73,53 @@ func (r *Reader) Reset(rd io.Reader) { r.rd.Reset(rd) } +// PeekReplyType returns the data type of the next response without advancing the Reader, +// and discard the attribute type. +func (r *Reader) PeekReplyType() (byte, error) { + b, err := r.rd.Peek(1) + if err != nil { + return 0, err + } + if b[0] == RespAttr { + if err = r.DiscardNext(); err != nil { + return 0, err + } + return r.PeekReplyType() + } + return b[0], nil +} + +// ReadLine Return a valid reply, it will check the protocol or redis error, +// and discard the attribute type. func (r *Reader) ReadLine() ([]byte, error) { line, err := r.readLine() if err != nil { return nil, err } - if isNilReply(line) { + switch line[0] { + case RespError: + return nil, ParseErrorReply(line) + case RespNil: + return nil, Nil + case RespBlobError: + var blobErr string + blobErr, err = r.readStringReply(line) + if err == nil { + err = RedisError(blobErr) + } + return nil, err + case RespAttr: + if err = r.Discard(line); err != nil { + return nil, err + } + return r.ReadLine() + } + + // Compatible with RESP2 + if IsNilReply(line) { return nil, Nil } + return line, nil } @@ -92,240 +150,373 @@ func (r *Reader) readLine() ([]byte, error) { return b[:len(b)-2], nil } -func (r *Reader) ReadReply(m MultiBulkParse) (interface{}, error) { +func (r *Reader) ReadReply() (interface{}, error) { line, err := r.ReadLine() if err != nil { return nil, err } switch line[0] { - case ErrorReply: - return nil, ParseErrorReply(line) - case StatusReply: + case RespStatus: return string(line[1:]), nil - case IntReply: + case RespInt: return util.ParseInt(line[1:], 10, 64) - case StringReply: + case RespFloat: + return r.readFloat(line) + case RespBool: + return r.readBool(line) + case RespBigInt: + return r.readBigInt(line) + + case RespString: return r.readStringReply(line) - case ArrayReply: - n, err := parseArrayLen(line) - if err != nil { - return nil, err - } - if m == nil { - err := fmt.Errorf("redis: got %.100q, but multi bulk parser is nil", line) - return nil, err - } - return m(r, n) + case RespVerbatim: + return r.readVerb(line) + + case RespArray, RespSet, RespPush: + return r.readSlice(line) + case RespMap: + return r.readMap(line) } return nil, fmt.Errorf("redis: can't parse %.100q", line) } -func (r *Reader) ReadIntReply() (int64, error) { - line, err := r.ReadLine() - if err != nil { - return 0, err - } - switch line[0] { - case ErrorReply: - return 0, ParseErrorReply(line) - case IntReply: - return util.ParseInt(line[1:], 10, 64) - default: - return 0, fmt.Errorf("redis: can't parse int reply: %.100q", line) +func (r *Reader) readFloat(line []byte) (float64, error) { + v := string(line[1:]) + switch string(line[1:]) { + case "inf": + return math.Inf(1), nil + case "-inf": + return math.Inf(-1), nil } + return strconv.ParseFloat(v, 64) } -func (r *Reader) ReadString() (string, error) { - line, err := r.ReadLine() - if err != nil { - return "", err +func (r *Reader) readBool(line []byte) (bool, error) { + switch string(line[1:]) { + case "t": + return true, nil + case "f": + return false, nil } - switch line[0] { - case ErrorReply: - return "", ParseErrorReply(line) - case StringReply: - return r.readStringReply(line) - case StatusReply: - return string(line[1:]), nil - case IntReply: - return string(line[1:]), nil - default: - return "", fmt.Errorf("redis: can't parse reply=%.100q reading string", line) + return false, fmt.Errorf("redis: can't parse bool reply: %q", line) +} + +func (r *Reader) readBigInt(line []byte) (*big.Int, error) { + i := new(big.Int) + if i, ok := i.SetString(string(line[1:]), 10); ok { + return i, nil } + return nil, fmt.Errorf("redis: can't parse bigInt reply: %q", line) } func (r *Reader) readStringReply(line []byte) (string, error) { - if isNilReply(line) { - return "", Nil + n, err := replyLen(line) + if err != nil { + return "", err } - replyLen, err := util.Atoi(line[1:]) + b := make([]byte, n+2) + _, err = io.ReadFull(r.rd, b) if err != nil { return "", err } - b := make([]byte, replyLen+2) - _, err = io.ReadFull(r.rd, b) + return util.BytesToString(b[:n]), nil +} + +func (r *Reader) readVerb(line []byte) (string, error) { + s, err := r.readStringReply(line) if err != nil { return "", err } + if len(s) < 4 || s[3] != ':' { + return "", fmt.Errorf("redis: can't parse verbatim string reply: %q", line) + } + return s[4:], nil +} - return util.BytesToString(b[:replyLen]), nil +func (r *Reader) readSlice(line []byte) ([]interface{}, error) { + n, err := replyLen(line) + if err != nil { + return nil, err + } + + val := make([]interface{}, n) + for i := 0; i < len(val); i++ { + v, err := r.ReadReply() + if err != nil { + if err == Nil { + val[i] = nil + continue + } + if err, ok := err.(RedisError); ok { + val[i] = err + continue + } + return nil, err + } + val[i] = v + } + return val, nil } -func (r *Reader) ReadArrayReply(m MultiBulkParse) (interface{}, error) { - line, err := r.ReadLine() +func (r *Reader) readMap(line []byte) (map[interface{}]interface{}, error) { + n, err := replyLen(line) if err != nil { return nil, err } - switch line[0] { - case ErrorReply: - return nil, ParseErrorReply(line) - case ArrayReply: - n, err := parseArrayLen(line) + m := make(map[interface{}]interface{}, n) + for i := 0; i < n; i++ { + k, err := r.ReadReply() if err != nil { return nil, err } - return m(r, n) - default: - return nil, fmt.Errorf("redis: can't parse array reply: %.100q", line) + v, err := r.ReadReply() + if err != nil { + if err == Nil { + m[k] = nil + continue + } + if err, ok := err.(RedisError); ok { + m[k] = err + continue + } + return nil, err + } + m[k] = v } + return m, nil } -func (r *Reader) ReadArrayLen() (int, error) { +// ------------------------------- + +func (r *Reader) ReadInt() (int64, error) { line, err := r.ReadLine() if err != nil { return 0, err } switch line[0] { - case ErrorReply: - return 0, ParseErrorReply(line) - case ArrayReply: - n, err := parseArrayLen(line) + case RespInt, RespStatus: + return util.ParseInt(line[1:], 10, 64) + case RespString: + s, err := r.readStringReply(line) if err != nil { return 0, err } - return int(n), nil - default: - return 0, fmt.Errorf("redis: can't parse array reply: %.100q", line) + return util.ParseInt([]byte(s), 10, 64) + case RespBigInt: + b, err := r.readBigInt(line) + if err != nil { + return 0, err + } + if !b.IsInt64() { + return 0, fmt.Errorf("bigInt(%s) value out of range", b.String()) + } + return b.Int64(), nil } + return 0, fmt.Errorf("redis: can't parse int reply: %.100q", line) } -func (r *Reader) ReadScanReply() ([]string, uint64, error) { - n, err := r.ReadArrayLen() +func (r *Reader) ReadFloat() (float64, error) { + line, err := r.ReadLine() if err != nil { - return nil, 0, err - } - if n != 2 { - return nil, 0, fmt.Errorf("redis: got %d elements in scan reply, expected 2", n) + return 0, err } - - cursor, err := r.ReadUint() - if err != nil { - return nil, 0, err + switch line[0] { + case RespFloat: + return r.readFloat(line) + case RespStatus: + return strconv.ParseFloat(string(line[1:]), 64) + case RespString: + s, err := r.readStringReply(line) + if err != nil { + return 0, err + } + return strconv.ParseFloat(s, 64) } + return 0, fmt.Errorf("redis: can't parse float reply: %.100q", line) +} - n, err = r.ReadArrayLen() +func (r *Reader) ReadString() (string, error) { + line, err := r.ReadLine() if err != nil { - return nil, 0, err + return "", err } - keys := make([]string, n) - - for i := 0; i < n; i++ { - key, err := r.ReadString() + switch line[0] { + case RespStatus, RespInt, RespFloat: + return string(line[1:]), nil + case RespString: + return r.readStringReply(line) + case RespBool: + b, err := r.readBool(line) + return strconv.FormatBool(b), err + case RespVerbatim: + return r.readVerb(line) + case RespBigInt: + b, err := r.readBigInt(line) if err != nil { - return nil, 0, err + return "", err } - keys[i] = key + return b.String(), nil } + return "", fmt.Errorf("redis: can't parse reply=%.100q reading string", line) +} - return keys, cursor, err +func (r *Reader) ReadBool() (bool, error) { + s, err := r.ReadString() + if err != nil { + return false, err + } + return s == "OK" || s == "1" || s == "true", nil } -func (r *Reader) ReadInt() (int64, error) { - b, err := r.readTmpBytesReply() +func (r *Reader) ReadSlice() ([]interface{}, error) { + line, err := r.ReadLine() if err != nil { - return 0, err + return nil, err } - return util.ParseInt(b, 10, 64) + return r.readSlice(line) } -func (r *Reader) ReadUint() (uint64, error) { - b, err := r.readTmpBytesReply() +// ReadFixedArrayLen read fixed array length. +func (r *Reader) ReadFixedArrayLen(fixedLen int) error { + n, err := r.ReadArrayLen() if err != nil { - return 0, err + return err } - return util.ParseUint(b, 10, 64) + if n != fixedLen { + return fmt.Errorf("redis: got %d elements of array length, wanted %d", n, fixedLen) + } + return nil } -func (r *Reader) ReadFloatReply() (float64, error) { - b, err := r.readTmpBytesReply() +// ReadArrayLen Read and return the length of the array. +func (r *Reader) ReadArrayLen() (int, error) { + line, err := r.ReadLine() if err != nil { return 0, err } - return util.ParseFloat(b, 64) + switch line[0] { + case RespArray, RespSet, RespPush: + return replyLen(line) + default: + return 0, fmt.Errorf("redis: can't parse array(array/set/push) reply: %.100q", line) + } +} + +// ReadFixedMapLen read fixed map length. +func (r *Reader) ReadFixedMapLen(fixedLen int) error { + n, err := r.ReadMapLen() + if err != nil { + return err + } + if n != fixedLen { + return fmt.Errorf("redis: got %d elements of map length, wanted %d", n, fixedLen) + } + return nil } -func (r *Reader) readTmpBytesReply() ([]byte, error) { +// ReadMapLen read the length of the map type. +// If responding to the array type (RespArray/RespSet/RespPush), +// it must be a multiple of 2 and return n/2. +// Other types will return an error. +func (r *Reader) ReadMapLen() (int, error) { line, err := r.ReadLine() if err != nil { - return nil, err + return 0, err } switch line[0] { - case ErrorReply: - return nil, ParseErrorReply(line) - case StringReply: - return r._readTmpBytesReply(line) - case StatusReply: - return line[1:], nil + case RespMap: + return replyLen(line) + case RespArray, RespSet, RespPush: + // Some commands and RESP2 protocol may respond to array types. + n, err := replyLen(line) + if err != nil { + return 0, err + } + if n%2 != 0 { + return 0, fmt.Errorf("redis: the length of the array must be a multiple of 2, got: %d", n) + } + return n / 2, nil default: - return nil, fmt.Errorf("redis: can't parse string reply: %.100q", line) + return 0, fmt.Errorf("redis: can't parse map reply: %.100q", line) } } -func (r *Reader) _readTmpBytesReply(line []byte) ([]byte, error) { - if isNilReply(line) { - return nil, Nil +// Discard the data represented by line. +func (r *Reader) Discard(line []byte) (err error) { + if len(line) == 0 { + return errors.New("redis: invalid line") + } + switch line[0] { + case RespStatus, RespError, RespInt, RespNil, RespFloat, RespBool, RespBigInt: + return nil } - replyLen, err := util.Atoi(line[1:]) - if err != nil { - return nil, err + n, err := replyLen(line) + if err != nil && err != Nil { + return err } - buf := r.buf(replyLen + 2) - _, err = io.ReadFull(r.rd, buf) - if err != nil { - return nil, err + switch line[0] { + case RespBlobError, RespString, RespVerbatim: + // +\r\n + _, err = r.rd.Discard(n + 2) + return err + case RespArray, RespSet, RespPush: + for i := 0; i < n; i++ { + if err = r.DiscardNext(); err != nil { + return err + } + } + return nil + case RespMap, RespAttr: + // Read key & value. + for i := 0; i < n*2; i++ { + if err = r.DiscardNext(); err != nil { + return err + } + } + return nil } - return buf[:replyLen], nil + return fmt.Errorf("redis: can't parse %.100q", line) } -func (r *Reader) buf(n int) []byte { - if n <= cap(r._buf) { - return r._buf[:n] +// DiscardNext read and discard the data represented by the next line. +func (r *Reader) DiscardNext() error { + line, err := r.readLine() + if err != nil { + return err } - d := n - cap(r._buf) - r._buf = append(r._buf, make([]byte, d)...) - return r._buf + return r.Discard(line) } -func isNilReply(b []byte) bool { - return len(b) == 3 && - (b[0] == StringReply || b[0] == ArrayReply) && - b[1] == '-' && b[2] == '1' -} +func replyLen(line []byte) (n int, err error) { + n, err = util.Atoi(line[1:]) + if err != nil { + return 0, err + } -func ParseErrorReply(line []byte) error { - return RedisError(string(line[1:])) -} + if n < -1 { + return 0, fmt.Errorf("redis: invalid reply: %q", line) + } -func parseArrayLen(line []byte) (int64, error) { - if isNilReply(line) { - return 0, Nil + switch line[0] { + case RespString, RespVerbatim, RespBlobError, + RespArray, RespSet, RespPush, RespMap, RespAttr: + if n == -1 { + return 0, Nil + } } - return util.ParseInt(line[1:], 10, 64) + return n, nil +} + +// IsNilReply detect redis.Nil of RESP2. +func IsNilReply(line []byte) bool { + return len(line) == 3 && + (line[0] == RespString || line[0] == RespArray) && + line[1] == '-' && line[2] == '1' } diff --git a/internal/proto/reader_test.go b/internal/proto/reader_test.go index b8c99dd613..9881047bf6 100644 --- a/internal/proto/reader_test.go +++ b/internal/proto/reader_test.go @@ -9,23 +9,63 @@ import ( ) func BenchmarkReader_ParseReply_Status(b *testing.B) { - benchmarkParseReply(b, "+OK\r\n", nil, false) + benchmarkParseReply(b, "+OK\r\n", false) } func BenchmarkReader_ParseReply_Int(b *testing.B) { - benchmarkParseReply(b, ":1\r\n", nil, false) + benchmarkParseReply(b, ":1\r\n", false) +} + +func BenchmarkReader_ParseReply_Float(b *testing.B) { + benchmarkParseReply(b, ",123.456\r\n", false) +} + +func BenchmarkReader_ParseReply_Bool(b *testing.B) { + benchmarkParseReply(b, "#t\r\n", false) +} + +func BenchmarkReader_ParseReply_BigInt(b *testing.B) { + benchmarkParseReply(b, "(3492890328409238509324850943850943825024385\r\n", false) } func BenchmarkReader_ParseReply_Error(b *testing.B) { - benchmarkParseReply(b, "-Error message\r\n", nil, true) + benchmarkParseReply(b, "-Error message\r\n", true) +} + +func BenchmarkReader_ParseReply_Nil(b *testing.B) { + benchmarkParseReply(b, "_\r\n", true) +} + +func BenchmarkReader_ParseReply_BlobError(b *testing.B) { + benchmarkParseReply(b, "!21\r\nSYNTAX invalid syntax", true) } func BenchmarkReader_ParseReply_String(b *testing.B) { - benchmarkParseReply(b, "$5\r\nhello\r\n", nil, false) + benchmarkParseReply(b, "$5\r\nhello\r\n", false) +} + +func BenchmarkReader_ParseReply_Verb(b *testing.B) { + benchmarkParseReply(b, "$9\r\ntxt:hello\r\n", false) } func BenchmarkReader_ParseReply_Slice(b *testing.B) { - benchmarkParseReply(b, "*2\r\n$5\r\nhello\r\n$5\r\nworld\r\n", multiBulkParse, false) + benchmarkParseReply(b, "*2\r\n$5\r\nhello\r\n$5\r\nworld\r\n", false) +} + +func BenchmarkReader_ParseReply_Set(b *testing.B) { + benchmarkParseReply(b, "~2\r\n$5\r\nhello\r\n$5\r\nworld\r\n", false) +} + +func BenchmarkReader_ParseReply_Push(b *testing.B) { + benchmarkParseReply(b, ">2\r\n$5\r\nhello\r\n$5\r\nworld\r\n", false) +} + +func BenchmarkReader_ParseReply_Map(b *testing.B) { + benchmarkParseReply(b, "%2\r\n$5\r\nhello\r\n$5\r\nworld\r\n+key\r\n+value\r\n", false) +} + +func BenchmarkReader_ParseReply_Attr(b *testing.B) { + benchmarkParseReply(b, "%1\r\n+key\r\n+value\r\n+hello\r\n", false) } func TestReader_ReadLine(t *testing.T) { @@ -43,7 +83,7 @@ func TestReader_ReadLine(t *testing.T) { } } -func benchmarkParseReply(b *testing.B, reply string, m proto.MultiBulkParse, wanterr bool) { +func benchmarkParseReply(b *testing.B, reply string, wanterr bool) { buf := new(bytes.Buffer) for i := 0; i < b.N; i++ { buf.WriteString(reply) @@ -52,21 +92,9 @@ func benchmarkParseReply(b *testing.B, reply string, m proto.MultiBulkParse, wan b.ResetTimer() for i := 0; i < b.N; i++ { - _, err := p.ReadReply(m) + _, err := p.ReadReply() if !wanterr && err != nil { b.Fatal(err) } } } - -func multiBulkParse(p *proto.Reader, n int64) (interface{}, error) { - vv := make([]interface{}, 0, n) - for i := int64(0); i < n; i++ { - v, err := p.ReadReply(multiBulkParse) - if err != nil { - return nil, err - } - vv = append(vv, v) - } - return vv, nil -} diff --git a/internal/proto/writer.go b/internal/proto/writer.go index 81b09b8e4f..72b30441b7 100644 --- a/internal/proto/writer.go +++ b/internal/proto/writer.go @@ -34,7 +34,7 @@ func NewWriter(wr writer) *Writer { } func (w *Writer) WriteArgs(args []interface{}) error { - if err := w.WriteByte(ArrayReply); err != nil { + if err := w.WriteByte(RespArray); err != nil { return err } @@ -111,7 +111,7 @@ func (w *Writer) WriteArg(v interface{}) error { } func (w *Writer) bytes(b []byte) error { - if err := w.WriteByte(StringReply); err != nil { + if err := w.WriteByte(RespString); err != nil { return err } diff --git a/pubsub_test.go b/pubsub_test.go index d32d5e0b19..b9633b2fc2 100644 --- a/pubsub_test.go +++ b/pubsub_test.go @@ -1,7 +1,6 @@ package redis_test import ( - "context" "io" "net" "sync" @@ -15,16 +14,11 @@ import ( var _ = Describe("PubSub", func() { var client *redis.Client - var clientID int64 BeforeEach(func() { opt := redisOptions() opt.MinIdleConns = 0 opt.MaxConnAge = 0 - opt.OnConnect = func(ctx context.Context, cn *redis.Conn) (err error) { - clientID, err = cn.ClientID(ctx).Result() - return err - } client = redis.NewClient(opt) Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred()) }) @@ -421,30 +415,6 @@ var _ = Describe("PubSub", func() { Expect(msg.Payload).To(Equal(string(bigVal))) }) - It("handles message payload slice with server-assisted client-size caching", func() { - pubsub := client.Subscribe(ctx, "__redis__:invalidate") - defer pubsub.Close() - - client2 := redis.NewClient(redisOptions()) - defer client2.Close() - - err := client2.Do(ctx, "CLIENT", "TRACKING", "on", "REDIRECT", clientID).Err() - Expect(err).NotTo(HaveOccurred()) - - err = client2.Do(ctx, "GET", "mykey").Err() - Expect(err).To(Equal(redis.Nil)) - - err = client2.Do(ctx, "SET", "mykey", "myvalue").Err() - Expect(err).NotTo(HaveOccurred()) - - ch := pubsub.Channel() - - var msg *redis.Message - Eventually(ch).Should(Receive(&msg)) - Expect(msg.Channel).To(Equal("__redis__:invalidate")) - Expect(msg.PayloadSlice).To(Equal([]string{"mykey"})) - }) - It("supports concurrent Ping and Receive", func() { const N = 100 diff --git a/redis.go b/redis.go index 7995c43657..8bf4403889 100644 --- a/redis.go +++ b/redis.go @@ -230,21 +230,21 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { } cn.Inited = true - if c.opt.Password == "" && - c.opt.DB == 0 && - !c.opt.readOnly && - c.opt.OnConnect == nil { - return nil - } - ctx, span := internal.StartSpan(ctx, "redis.init_conn") defer span.End() connPool := pool.NewSingleConnPool(c.connPool, cn) conn := newConn(ctx, c.opt, connPool) + var auth bool + + // The low version of redis-server does not support the hello command. + if conn.Hello(ctx, 3, c.opt.Username, c.opt.Password, "").Err() == nil { + auth = true + } + _, err := conn.Pipelined(ctx, func(pipe Pipeliner) error { - if c.opt.Password != "" { + if !auth && c.opt.Password != "" { if c.opt.Username != "" { pipe.AuthACL(ctx, c.opt.Username, c.opt.Password) } else { @@ -542,14 +542,8 @@ func txPipelineReadQueued(rd *proto.Reader, statusCmd *StatusCmd, cmds []Cmder) return err } - switch line[0] { - case proto.ErrorReply: - return proto.ParseErrorReply(line) - case proto.ArrayReply: - // ok - default: - err := fmt.Errorf("redis: expected '*', but got line %q", line) - return err + if line[0] != proto.RespArray { + return fmt.Errorf("redis: expected '*', but got line %q", line) } return nil diff --git a/result.go b/result.go index 24cfd49940..5043bf9321 100644 --- a/result.go +++ b/result.go @@ -83,8 +83,8 @@ func NewBoolSliceResult(val []bool, err error) *BoolSliceCmd { } // NewStringStringMapResult returns a StringStringMapCmd initialised with val and err for testing. -func NewStringStringMapResult(val map[string]string, err error) *StringStringMapCmd { - var cmd StringStringMapCmd +func NewStringStringMapResult(val map[string]string, err error) *MapStringStringCmd { + var cmd MapStringStringCmd cmd.val = val cmd.SetErr(err) return &cmd diff --git a/ring_test.go b/ring_test.go index 2189cd63e9..4a434a5b52 100644 --- a/ring_test.go +++ b/ring_test.go @@ -177,6 +177,7 @@ var _ = Describe("Redis Ring", func() { It("can be initialized with a new client callback", func() { opts := redisRingOptions() opts.NewClient = func(name string, opt *redis.Options) *redis.Client { + opt.Username = "username1" opt.Password = "password1" return redis.NewClient(opt) } @@ -184,7 +185,7 @@ var _ = Describe("Redis Ring", func() { err := ring.Ping(ctx).Err() Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("ERR AUTH")) + Expect(err.Error()).To(ContainSubstring("WRONGPASS")) }) }) diff --git a/sentinel.go b/sentinel.go index ca2e088a76..15f3366dc9 100644 --- a/sentinel.go +++ b/sentinel.go @@ -322,8 +322,8 @@ func (c *SentinelClient) GetMasterAddrByName(ctx context.Context, name string) * return cmd } -func (c *SentinelClient) Sentinels(ctx context.Context, name string) *SliceCmd { - cmd := NewSliceCmd(ctx, "sentinel", "sentinels", name) +func (c *SentinelClient) Sentinels(ctx context.Context, name string) *MapStringStringSliceCmd { + cmd := NewMapStringStringSliceCmd(ctx, "sentinel", "sentinels", name) _ = c.Process(ctx, cmd) return cmd } @@ -355,8 +355,8 @@ func (c *SentinelClient) FlushConfig(ctx context.Context) *StatusCmd { } // Master shows the state and info of the specified master. -func (c *SentinelClient) Master(ctx context.Context, name string) *StringStringMapCmd { - cmd := NewStringStringMapCmd(ctx, "sentinel", "master", name) +func (c *SentinelClient) Master(ctx context.Context, name string) *MapStringStringCmd { + cmd := NewMapStringStringCmd(ctx, "sentinel", "master", name) _ = c.Process(ctx, cmd) return cmd } @@ -369,8 +369,8 @@ func (c *SentinelClient) Masters(ctx context.Context) *SliceCmd { } // Slaves shows a list of slaves for the specified master and their state. -func (c *SentinelClient) Slaves(ctx context.Context, name string) *SliceCmd { - cmd := NewSliceCmd(ctx, "sentinel", "slaves", name) +func (c *SentinelClient) Slaves(ctx context.Context, name string) *MapStringStringSliceCmd { + cmd := NewMapStringStringSliceCmd(ctx, "sentinel", "slaves", name) _ = c.Process(ctx, cmd) return cmd } @@ -588,40 +588,24 @@ func (c *sentinelFailover) getSlaveAddrs(ctx context.Context, sentinel *Sentinel return parseSlaveAddrs(addrs, false) } -func parseSlaveAddrs(addrs []interface{}, keepDisconnected bool) []string { +func parseSlaveAddrs(addrs []map[string]string, keepDisconnected bool) []string { nodes := make([]string, 0, len(addrs)) for _, node := range addrs { - ip := "" - port := "" - flags := []string{} - lastkey := "" isDown := false - - for _, key := range node.([]interface{}) { - switch lastkey { - case "ip": - ip = key.(string) - case "port": - port = key.(string) - case "flags": - flags = strings.Split(key.(string), ",") - } - lastkey = key.(string) - } - - for _, flag := range flags { - switch flag { - case "s_down", "o_down": - isDown = true - case "disconnected": - if !keepDisconnected { + if flags, ok := node["flags"]; ok { + for _, flag := range strings.Split(flags, ",") { + switch flag { + case "s_down", "o_down": isDown = true + case "disconnected": + if !keepDisconnected { + isDown = true + } } } } - - if !isDown { - nodes = append(nodes, net.JoinHostPort(ip, port)) + if !isDown && node["ip"] != "" && node["port"] != "" { + nodes = append(nodes, net.JoinHostPort(node["ip"], node["port"])) } } @@ -670,16 +654,13 @@ func (c *sentinelFailover) discoverSentinels(ctx context.Context) { return } for _, sentinel := range sentinels { - vals := sentinel.([]interface{}) - var ip, port string - for i := 0; i < len(vals); i += 2 { - key := vals[i].(string) - switch key { - case "ip": - ip = vals[i+1].(string) - case "port": - port = vals[i+1].(string) - } + ip, ok := sentinel["ip"] + if !ok { + continue + } + port, ok := sentinel["port"] + if !ok { + continue } if ip != "" && port != "" { sentinelAddr := net.JoinHostPort(ip, port) diff --git a/sentinel_test.go b/sentinel_test.go index 7b4aabdbb2..f5cfa3d3e3 100644 --- a/sentinel_test.go +++ b/sentinel_test.go @@ -185,7 +185,8 @@ var _ = Describe("NewFailoverClusterClient", func() { } // Create subscription. - ch := client.Subscribe(ctx, "foo").Channel() + sub := client.Subscribe(ctx, "foo") + ch := sub.Channel() // Kill master. err = master.Shutdown(ctx).Err() @@ -207,6 +208,7 @@ var _ = Describe("NewFailoverClusterClient", func() { }, "15s", "100ms").Should(Receive(&msg)) Expect(msg.Channel).To(Equal("foo")) Expect(msg.Payload).To(Equal("hello")) + Expect(sub.Close()).NotTo(HaveOccurred()) _, err = startRedis(masterPort) Expect(err).NotTo(HaveOccurred()) From 5ed546f303dae50ac28e5b9296c2b1523119fd4c Mon Sep 17 00:00:00 2001 From: nigel_li Date: Wed, 28 Apr 2021 13:56:44 +0800 Subject: [PATCH 002/621] Add command SMISMEMBER --- commands.go | 12 ++++++++++++ commands_test.go | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/commands.go b/commands.go index 65ca464004..0926b8708e 100644 --- a/commands.go +++ b/commands.go @@ -201,6 +201,7 @@ type Cmdable interface { SInter(ctx context.Context, keys ...string) *StringSliceCmd SInterStore(ctx context.Context, destination string, keys ...string) *IntCmd SIsMember(ctx context.Context, key string, member interface{}) *BoolCmd + SMIsMember(ctx context.Context, key string, members ...interface{}) *BoolSliceCmd SMembers(ctx context.Context, key string) *StringSliceCmd SMembersMap(ctx context.Context, key string) *StringStructMapCmd SMove(ctx context.Context, source, destination string, member interface{}) *BoolCmd @@ -1530,6 +1531,17 @@ func (c cmdable) SIsMember(ctx context.Context, key string, member interface{}) return cmd } +// Redis `SMISMEMBER key member [member ...]` command. +func (c cmdable) SMIsMember(ctx context.Context, key string, members ...interface{}) *BoolSliceCmd { + args := make([]interface{}, 2, 2+len(members)) + args[0] = "smismember" + args[1] = key + args = appendArgs(args, members) + cmd := NewBoolSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + // Redis `SMEMBERS key` command output as a slice. func (c cmdable) SMembers(ctx context.Context, key string) *StringSliceCmd { cmd := NewStringSliceCmd(ctx, "smembers", key) diff --git a/commands_test.go b/commands_test.go index 144958746f..fb492bfb53 100644 --- a/commands_test.go +++ b/commands_test.go @@ -2500,6 +2500,15 @@ var _ = Describe("Commands", func() { Expect(sIsMember.Val()).To(Equal(false)) }) + It("should SMIsMember", func() { + sAdd := client.SAdd(ctx, "set", "one") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + + sMIsMember := client.SMIsMember(ctx, "set", "one", "two") + Expect(sMIsMember.Err()).NotTo(HaveOccurred()) + Expect(sMIsMember.Val()).To(Equal([]bool{true, false})) + }) + It("should SMembers", func() { sAdd := client.SAdd(ctx, "set", "Hello") Expect(sAdd.Err()).NotTo(HaveOccurred()) From eca1bb6b36886b069cd96c8470044d6e3ea11bd5 Mon Sep 17 00:00:00 2001 From: nigel_li Date: Wed, 28 Apr 2021 14:39:03 +0800 Subject: [PATCH 003/621] Use the right redis client in tests --- commands_test.go | 2 +- redis_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/commands_test.go b/commands_test.go index fb492bfb53..f42792c451 100644 --- a/commands_test.go +++ b/commands_test.go @@ -4702,7 +4702,7 @@ var _ = Describe("Commands", func() { client.ConfigSet(ctx, key, "0") defer client.ConfigSet(ctx, key, old[key]) - err := rdb.Do(ctx, "slowlog", "reset").Err() + err := client.Do(ctx, "slowlog", "reset").Err() Expect(err).NotTo(HaveOccurred()) client.Set(ctx, "test", "true", 0) diff --git a/redis_test.go b/redis_test.go index bbfa4c140a..9f189052dc 100644 --- a/redis_test.go +++ b/redis_test.go @@ -290,18 +290,18 @@ var _ = Describe("Client", func() { It("should set and scan time", func() { tm := time.Now() - err := rdb.Set(ctx, "now", tm, 0).Err() + err := client.Set(ctx, "now", tm, 0).Err() Expect(err).NotTo(HaveOccurred()) var tm2 time.Time - err = rdb.Get(ctx, "now").Scan(&tm2) + err = client.Get(ctx, "now").Scan(&tm2) Expect(err).NotTo(HaveOccurred()) Expect(tm2).To(BeTemporally("==", tm)) }) It("should Conn", func() { - err := rdb.Conn(ctx).Get(ctx, "this-key-does-not-exist").Err() + err := client.Conn(ctx).Get(ctx, "this-key-does-not-exist").Err() Expect(err).To(Equal(redis.Nil)) }) }) From b60d47d3291da41616c5943b2e504ae46c95354d Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Thu, 13 May 2021 09:25:36 +0300 Subject: [PATCH 004/621] Tweak comments --- redis.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/redis.go b/redis.go index 8bf4403889..aeb7f4ea83 100644 --- a/redis.go +++ b/redis.go @@ -551,9 +551,11 @@ func txPipelineReadQueued(rd *proto.Reader, statusCmd *StatusCmd, cmds []Cmder) //------------------------------------------------------------------------------ -// Client is a Redis client representing a pool of zero or more -// underlying connections. It's safe for concurrent use by multiple -// goroutines. +// Client is a Redis client representing a pool of zero or more underlying connections. +// It's safe for concurrent use by multiple goroutines. +// +// Client creates and frees connections automatically; it also maintains a free pool +// of idle connections. You can control the pool size with Config.PoolSize option. type Client struct { *baseClient cmdable @@ -729,7 +731,11 @@ type conn struct { hooks // TODO: inherit hooks } -// Conn is like Client, but its pool contains single connection. +// Conn represents a single Redis connection rather than a pool of database connections. +// It's safe for concurrent use by multiple goroutines. + +// Prefer running commands from Client unless there is a specific need for a continuous +// single Redis connection. type Conn struct { *conn ctx context.Context From 81df6895a8d98b689b354e620bb681f4ffa24da5 Mon Sep 17 00:00:00 2001 From: monkey Date: Thu, 13 May 2021 17:56:51 +0800 Subject: [PATCH 005/621] fix comments Signed-off-by: monkey --- redis.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redis.go b/redis.go index aeb7f4ea83..cce5fb9267 100644 --- a/redis.go +++ b/redis.go @@ -733,7 +733,7 @@ type conn struct { // Conn represents a single Redis connection rather than a pool of database connections. // It's safe for concurrent use by multiple goroutines. - +// // Prefer running commands from Client unless there is a specific need for a continuous // single Redis connection. type Conn struct { From d42071c47a72804a5a47ed373e16699b68f19564 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Mon, 17 May 2021 11:56:12 +0300 Subject: [PATCH 006/621] Replace go-pg with bun --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1a0e460e58..e58d867df9 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,5 @@ go test ## See also -- [Fast and flexible HTTP router](https://github.com/vmihailenco/treemux) -- [Golang PostgreSQL ORM](https://github.com/go-pg/pg) -- [Golang msgpack](https://github.com/vmihailenco/msgpack) -- [Golang message task queue](https://github.com/vmihailenco/taskq) +- [Fast and flexible ORM](https://github.com/uptrace/bun) +- [msgpack for Go](https://github.com/vmihailenco/msgpack) From fe9bc126b7edd0d72c3861d57f3b730181f42fa2 Mon Sep 17 00:00:00 2001 From: monkey92t Date: Wed, 19 May 2021 17:43:31 +0800 Subject: [PATCH 007/621] sync master to v9 (#1760) * Added missing idle args in XPendingExtArgs (#1750) Added missing idle args in XPendingExtArgs * fix #1754 (#1756) * Replace go-pg with bun * fix #1755 Signed-off-by: monkey * fix read data Signed-off-by: monkey * fix #1758 (#1759) fix #1758 Co-authored-by: Parvez Co-authored-by: Vladimir Mihailenco --- .github/workflows/build.yml | 2 +- .github/workflows/golangci-lint.yml | 1 + command.go | 279 +++++++++++++++++++++++++++- commands.go | 29 ++- commands_test.go | 177 +++++++++++++++++- 5 files changed, 481 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e6858a324c..59ee91cb75 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Go on: push: - branches: [master] + branches: [master, v9] pull_request: branches: [master, v9] diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 6c12b83b35..1d9708c0ab 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -7,6 +7,7 @@ on: branches: - master - main + - v9 pull_request: jobs: diff --git a/command.go b/command.go index 28fd8c13e9..74f8924687 100644 --- a/command.go +++ b/command.go @@ -1520,7 +1520,7 @@ type XInfoConsumer struct { Idle int64 } -var _ Cmder = (*XInfoGroupsCmd)(nil) +var _ Cmder = (*XInfoConsumersCmd)(nil) func NewXInfoConsumersCmd(ctx context.Context, stream string, group string) *XInfoConsumersCmd { return &XInfoConsumersCmd{ @@ -1722,8 +1722,14 @@ func (cmd *XInfoStreamCmd) readReply(rd *proto.Reader) error { cmd.val.LastGeneratedID, err = rd.ReadString() case "first-entry": cmd.val.FirstEntry, err = readXMessage(rd) + if err == Nil { + err = nil + } case "last-entry": cmd.val.LastEntry, err = readXMessage(rd) + if err == Nil { + err = nil + } default: return fmt.Errorf("redis: unexpected content %s "+ "in XINFO STREAM reply", key) @@ -1737,6 +1743,277 @@ func (cmd *XInfoStreamCmd) readReply(rd *proto.Reader) error { //------------------------------------------------------------------------------ +type XInfoStreamFullCmd struct { + baseCmd + val *XInfoStreamFull +} + +type XInfoStreamFull struct { + Length int64 + RadixTreeKeys int64 + RadixTreeNodes int64 + LastGeneratedID string + Entries []XMessage + Groups []XInfoStreamGroup +} + +type XInfoStreamGroup struct { + Name string + LastDeliveredID string + PelCount int64 + Pending []XInfoStreamGroupPending + Consumers []XInfoStreamConsumer +} + +type XInfoStreamGroupPending struct { + ID string + Consumer string + DeliveryTime time.Time + DeliveryCount int64 +} + +type XInfoStreamConsumer struct { + Name string + SeenTime time.Time + PelCount int64 + Pending []XInfoStreamConsumerPending +} + +type XInfoStreamConsumerPending struct { + ID string + DeliveryTime time.Time + DeliveryCount int64 +} + +var _ Cmder = (*XInfoStreamFullCmd)(nil) + +func NewXInfoStreamFullCmd(ctx context.Context, args ...interface{}) *XInfoStreamFullCmd { + return &XInfoStreamFullCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *XInfoStreamFullCmd) Val() *XInfoStreamFull { + return cmd.val +} + +func (cmd *XInfoStreamFullCmd) Result() (*XInfoStreamFull, error) { + return cmd.val, cmd.err +} + +func (cmd *XInfoStreamFullCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XInfoStreamFullCmd) readReply(rd *proto.Reader) error { + if err := rd.ReadFixedMapLen(6); err != nil { + return err + } + + cmd.val = &XInfoStreamFull{} + + for i := 0; i < 6; i++ { + key, err := rd.ReadString() + if err != nil { + return err + } + + switch key { + case "length": + cmd.val.Length, err = rd.ReadInt() + case "radix-tree-keys": + cmd.val.RadixTreeKeys, err = rd.ReadInt() + case "radix-tree-nodes": + cmd.val.RadixTreeNodes, err = rd.ReadInt() + case "last-generated-id": + cmd.val.LastGeneratedID, err = rd.ReadString() + case "entries": + cmd.val.Entries, err = readXMessageSlice(rd) + case "groups": + cmd.val.Groups, err = readStreamGroups(rd) + default: + return fmt.Errorf("redis: unexpected content %s "+ + "in XINFO STREAM FULL reply", key) + } + if err != nil { + return err + } + } + return nil +} + +func readStreamGroups(rd *proto.Reader) ([]XInfoStreamGroup, error) { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + groups := make([]XInfoStreamGroup, 0, n) + for i := 0; i < n; i++ { + if err = rd.ReadFixedMapLen(5); err != nil { + return nil, err + } + + group := XInfoStreamGroup{} + + for f := 0; f < 5; f++ { + key, err := rd.ReadString() + if err != nil { + return nil, err + } + + switch key { + case "name": + group.Name, err = rd.ReadString() + case "last-delivered-id": + group.LastDeliveredID, err = rd.ReadString() + case "pel-count": + group.PelCount, err = rd.ReadInt() + case "pending": + group.Pending, err = readXInfoStreamGroupPending(rd) + case "consumers": + group.Consumers, err = readXInfoStreamConsumers(rd) + default: + return nil, fmt.Errorf("redis: unexpected content %s "+ + "in XINFO STREAM FULL reply", key) + } + + if err != nil { + return nil, err + } + } + + groups = append(groups, group) + } + + return groups, nil +} + +func readXInfoStreamGroupPending(rd *proto.Reader) ([]XInfoStreamGroupPending, error) { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + + pending := make([]XInfoStreamGroupPending, 0, n) + + for i := 0; i < n; i++ { + if err = rd.ReadFixedArrayLen(4); err != nil { + return nil, err + } + + p := XInfoStreamGroupPending{} + + p.ID, err = rd.ReadString() + if err != nil { + return nil, err + } + + p.Consumer, err = rd.ReadString() + if err != nil { + return nil, err + } + + delivery, err := rd.ReadInt() + if err != nil { + return nil, err + } + p.DeliveryTime = time.Unix(delivery/1000, delivery%1000*int64(time.Millisecond)) + + p.DeliveryCount, err = rd.ReadInt() + if err != nil { + return nil, err + } + + pending = append(pending, p) + } + + return pending, nil +} + +func readXInfoStreamConsumers(rd *proto.Reader) ([]XInfoStreamConsumer, error) { + n, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + + consumers := make([]XInfoStreamConsumer, 0, n) + + for i := 0; i < n; i++ { + if err = rd.ReadFixedMapLen(4); err != nil { + return nil, err + } + + c := XInfoStreamConsumer{} + + for f := 0; f < 4; f++ { + cKey, err := rd.ReadString() + if err != nil { + return nil, err + } + + switch cKey { + case "name": + c.Name, err = rd.ReadString() + case "seen-time": + seen, err := rd.ReadInt() + if err != nil { + return nil, err + } + c.SeenTime = time.Unix(seen/1000, seen%1000*int64(time.Millisecond)) + case "pel-count": + c.PelCount, err = rd.ReadInt() + case "pending": + pendingNumber, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + + c.Pending = make([]XInfoStreamConsumerPending, 0, pendingNumber) + + for pn := 0; pn < pendingNumber; pn++ { + if err = rd.ReadFixedArrayLen(3); err != nil { + return nil, err + } + + p := XInfoStreamConsumerPending{} + + p.ID, err = rd.ReadString() + if err != nil { + return nil, err + } + + delivery, err := rd.ReadInt() + if err != nil { + return nil, err + } + p.DeliveryTime = time.Unix(delivery/1000, delivery%1000*int64(time.Millisecond)) + + p.DeliveryCount, err = rd.ReadInt() + if err != nil { + return nil, err + } + + c.Pending = append(c.Pending, p) + } + default: + return nil, fmt.Errorf("redis: unexpected content %s "+ + "in XINFO STREAM FULL reply", cKey) + } + if err != nil { + return nil, err + } + } + consumers = append(consumers, c) + } + + return consumers, nil +} + +//------------------------------------------------------------------------------ + type ZSliceCmd struct { baseCmd diff --git a/commands.go b/commands.go index 0926b8708e..7990b72eb2 100644 --- a/commands.go +++ b/commands.go @@ -180,6 +180,7 @@ type Cmdable interface { LInsertAfter(ctx context.Context, key string, pivot, value interface{}) *IntCmd LLen(ctx context.Context, key string) *IntCmd LPop(ctx context.Context, key string) *StringCmd + LPopCount(ctx context.Context, key string, count int) *StringSliceCmd LPos(ctx context.Context, key string, value string, args LPosArgs) *IntCmd LPosCount(ctx context.Context, key string, value string, count int64, args LPosArgs) *IntSliceCmd LPush(ctx context.Context, key string, values ...interface{}) *IntCmd @@ -1336,6 +1337,12 @@ func (c cmdable) LPop(ctx context.Context, key string) *StringCmd { return cmd } +func (c cmdable) LPopCount(ctx context.Context, key string, count int) *StringSliceCmd { + cmd := NewStringSliceCmd(ctx, "lpop", key, count) + _ = c(ctx, cmd) + return cmd +} + type LPosArgs struct { Rank, MaxLen int64 } @@ -1833,6 +1840,7 @@ func (c cmdable) XPending(ctx context.Context, stream, group string) *XPendingCm type XPendingExtArgs struct { Stream string Group string + Idle time.Duration Start string End string Count int64 @@ -1840,8 +1848,12 @@ type XPendingExtArgs struct { } func (c cmdable) XPendingExt(ctx context.Context, a *XPendingExtArgs) *XPendingExtCmd { - args := make([]interface{}, 0, 7) - args = append(args, "xpending", a.Stream, a.Group, a.Start, a.End, a.Count) + args := make([]interface{}, 0, 9) + args = append(args, "xpending", a.Stream, a.Group) + if a.Idle != 0 { + args = append(args, "idle", formatMs(ctx, a.Idle)) + } + args = append(args, a.Start, a.End, a.Count) if a.Consumer != "" { args = append(args, a.Consumer) } @@ -1916,6 +1928,19 @@ func (c cmdable) XInfoStream(ctx context.Context, key string) *XInfoStreamCmd { return cmd } +// XInfoStreamFull XINFO STREAM FULL [COUNT count] +// redis-server >= 6.0. +func (c cmdable) XInfoStreamFull(ctx context.Context, key string, count int) *XInfoStreamFullCmd { + args := make([]interface{}, 0, 6) + args = append(args, "xinfo", "stream", key, "full") + if count > 0 { + args = append(args, "count", count) + } + cmd := NewXInfoStreamFullCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + //------------------------------------------------------------------------------ // Z represents sorted set member. diff --git a/commands_test.go b/commands_test.go index f42792c451..3db4fe0293 100644 --- a/commands_test.go +++ b/commands_test.go @@ -2064,6 +2064,25 @@ var _ = Describe("Commands", func() { Expect(lRange.Val()).To(Equal([]string{"two", "three"})) }) + It("should LPopCount", func() { + rPush := client.RPush(ctx, "list", "one") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "two") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "three") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "four") + Expect(rPush.Err()).NotTo(HaveOccurred()) + + lPopCount := client.LPopCount(ctx, "list", 2) + Expect(lPopCount.Err()).NotTo(HaveOccurred()) + Expect(lPopCount.Val()).To(Equal([]string{"one", "two"})) + + lRange := client.LRange(ctx, "list", 0, -1) + Expect(lRange.Err()).NotTo(HaveOccurred()) + Expect(lRange.Val()).To(Equal([]string{"three", "four"})) + }) + It("should LPos", func() { rPush := client.RPush(ctx, "list", "a") Expect(rPush.Err()).NotTo(HaveOccurred()) @@ -4241,15 +4260,15 @@ var _ = Describe("Commands", func() { Higher: "3-0", Consumers: map[string]int64{"consumer": 3}, })) - - infoExt, err := client.XPendingExt(ctx, &redis.XPendingExtArgs{ + args := &redis.XPendingExtArgs{ Stream: "stream", Group: "group", Start: "-", End: "+", Count: 10, Consumer: "consumer", - }).Result() + } + infoExt, err := client.XPendingExt(ctx, args).Result() Expect(err).NotTo(HaveOccurred()) for i := range infoExt { infoExt[i].Idle = 0 @@ -4260,6 +4279,11 @@ var _ = Describe("Commands", func() { {ID: "3-0", Consumer: "consumer", Idle: 0, RetryCount: 1}, })) + args.Idle = 72 * time.Hour + infoExt, err = client.XPendingExt(ctx, args).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(infoExt).To(HaveLen(0)) + n, err := client.XGroupDelConsumer(ctx, "stream", "group", "consumer").Result() Expect(err).NotTo(HaveOccurred()) Expect(n).To(Equal(int64(3))) @@ -4382,6 +4406,153 @@ var _ = Describe("Commands", func() { FirstEntry: redis.XMessage{ID: "1-0", Values: map[string]interface{}{"uno": "un"}}, LastEntry: redis.XMessage{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}}, })) + + // stream is empty + n, err := client.XDel(ctx, "stream", "1-0", "2-0", "3-0").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(n).To(Equal(int64(3))) + + res, err = client.XInfoStream(ctx, "stream").Result() + Expect(err).NotTo(HaveOccurred()) + res.RadixTreeKeys = 0 + res.RadixTreeNodes = 0 + + Expect(res).To(Equal(&redis.XInfoStream{ + Length: 0, + RadixTreeKeys: 0, + RadixTreeNodes: 0, + Groups: 2, + LastGeneratedID: "3-0", + FirstEntry: redis.XMessage{}, + LastEntry: redis.XMessage{}, + })) + }) + + It("should XINFO STREAM FULL", func() { + res, err := client.XInfoStreamFull(ctx, "stream", 2).Result() + Expect(err).NotTo(HaveOccurred()) + res.RadixTreeKeys = 0 + res.RadixTreeNodes = 0 + + // Verify DeliveryTime + now := time.Now() + maxElapsed := 10 * time.Minute + for k, g := range res.Groups { + for k2, p := range g.Pending { + Expect(now.Sub(p.DeliveryTime)).To(BeNumerically("<=", maxElapsed)) + res.Groups[k].Pending[k2].DeliveryTime = time.Time{} + } + for k3, c := range g.Consumers { + Expect(now.Sub(c.SeenTime)).To(BeNumerically("<=", maxElapsed)) + res.Groups[k].Consumers[k3].SeenTime = time.Time{} + + for k4, p := range c.Pending { + Expect(now.Sub(p.DeliveryTime)).To(BeNumerically("<=", maxElapsed)) + res.Groups[k].Consumers[k3].Pending[k4].DeliveryTime = time.Time{} + } + } + } + + Expect(res).To(Equal(&redis.XInfoStreamFull{ + Length: 3, + RadixTreeKeys: 0, + RadixTreeNodes: 0, + LastGeneratedID: "3-0", + Entries: []redis.XMessage{ + {ID: "1-0", Values: map[string]interface{}{"uno": "un"}}, + {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}}, + }, + Groups: []redis.XInfoStreamGroup{ + { + Name: "group1", + LastDeliveredID: "3-0", + PelCount: 3, + Pending: []redis.XInfoStreamGroupPending{ + { + ID: "1-0", + Consumer: "consumer1", + DeliveryTime: time.Time{}, + DeliveryCount: 1, + }, + { + ID: "2-0", + Consumer: "consumer1", + DeliveryTime: time.Time{}, + DeliveryCount: 1, + }, + }, + Consumers: []redis.XInfoStreamConsumer{ + { + Name: "consumer1", + SeenTime: time.Time{}, + PelCount: 2, + Pending: []redis.XInfoStreamConsumerPending{ + { + ID: "1-0", + DeliveryTime: time.Time{}, + DeliveryCount: 1, + }, + { + ID: "2-0", + DeliveryTime: time.Time{}, + DeliveryCount: 1, + }, + }, + }, + { + Name: "consumer2", + SeenTime: time.Time{}, + PelCount: 1, + Pending: []redis.XInfoStreamConsumerPending{ + { + ID: "3-0", + DeliveryTime: time.Time{}, + DeliveryCount: 1, + }, + }, + }, + }, + }, + { + Name: "group2", + LastDeliveredID: "3-0", + PelCount: 2, + Pending: []redis.XInfoStreamGroupPending{ + { + ID: "2-0", + Consumer: "consumer1", + DeliveryTime: time.Time{}, + DeliveryCount: 1, + }, + { + ID: "3-0", + Consumer: "consumer1", + DeliveryTime: time.Time{}, + DeliveryCount: 1, + }, + }, + Consumers: []redis.XInfoStreamConsumer{ + { + Name: "consumer1", + SeenTime: time.Time{}, + PelCount: 2, + Pending: []redis.XInfoStreamConsumerPending{ + { + ID: "2-0", + DeliveryTime: time.Time{}, + DeliveryCount: 1, + }, + { + ID: "3-0", + DeliveryTime: time.Time{}, + DeliveryCount: 1, + }, + }, + }, + }, + }, + }, + })) }) It("should XINFO GROUPS", func() { From 63df0e5e75b8842c1d1bf52f0506682d0a5989c8 Mon Sep 17 00:00:00 2001 From: monkey92t Date: Mon, 28 Jun 2021 17:40:38 +0800 Subject: [PATCH 008/621] sync master (#1800) * Remove OpenTelemetry from the code (but leave redisotel as is) (#1782) * Add XAutoClaim command (#1780) * fix typo (#1788) * xgroup/xadd/xtrim supports new options (#1787) * support cmd option XGROUP CREATECONSUMER XTRIM MINID LIMIT XADD NOMKSTREAM MINID LIMIT Signed-off-by: monkey * add XAddArgs.Approx doc Signed-off-by: monkey92t * Add Bun to readme * Upgrade the series of commands (#1792) * Upgrade the series of commands Signed-off-by: monkey92t * Cancel the Deprecated mark of ZAddNX and ZAddXX Signed-off-by: monkey92t * Explain the use restrictions of KeepTTL. (#1799) Signed-off-by: monkey92t * Adjust KeepTTL annotation. Signed-off-by: monkey92t * the hello command throws possible errors, It may affect the "read timeout" test result. Signed-off-by: monkey92t Co-authored-by: Vladimir Mihailenco Co-authored-by: ericmillin <31105612+ericmillin@users.noreply.github.com> Co-authored-by: heyanfu <1145291570@qq.com> --- CHANGELOG.md | 13 + README.md | 8 +- bench_test.go | 2 +- command.go | 106 +++++++ commands.go | 532 ++++++++++++++++++++++----------- commands_test.go | 648 ++++++++++++++++++++++++++++------------ example_test.go | 4 +- go.mod | 2 - internal/hscan/hscan.go | 2 +- internal/pool/conn.go | 19 +- internal/util.go | 24 -- options.go | 18 +- redis.go | 19 +- 13 files changed, 948 insertions(+), 449 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b540a4f18..42d89b720e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ > :heart: > [**Uptrace.dev** - All-in-one tool to optimize performance and monitor errors & logs](https://uptrace.dev) +## v8.10 + +- Removed extra OpenTelemetry spans from go-redis core. Now go-redis instrumentation only adds a + single span with a Redis command (instead of 4 spans). There are multiple reasons behind this + decision: + + - Traces become smaller and less noisy. + - It may be costly to process those 3 extra spans for each query. + - go-redis no longer depends on OpenTelemetry. + + Eventually we hope to replace the information that we no longer collect with OpenTelemetry + Metrics. + ## v8.9 - Changed `PubSub.Channel` to only rely on `Ping` result. You can now use `WithChannelSize`, diff --git a/README.md b/README.md index e58d867df9..5f52a55243 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,9 @@ - [Examples](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#pkg-examples) - [RealWorld example app](https://github.com/uptrace/go-treemux-realworld-example-app) +> :heart: Please check [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, +> MySQL, and SQLite. + ## Ecosystem - [Redis Mock](https://github.com/go-redis/redismock). @@ -160,8 +163,3 @@ Lastly, run: ``` go test ``` - -## See also - -- [Fast and flexible ORM](https://github.com/uptrace/bun) -- [msgpack for Go](https://github.com/vmihailenco/msgpack) diff --git a/bench_test.go b/bench_test.go index 708da5d958..0f26152dbf 100644 --- a/bench_test.go +++ b/bench_test.go @@ -222,7 +222,7 @@ func BenchmarkZAdd(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { - err := client.ZAdd(ctx, "key", &redis.Z{ + err := client.ZAdd(ctx, "key", redis.Z{ Score: float64(1), Member: "hello", }).Err() diff --git a/command.go b/command.go index 74f8924687..1c53a66060 100644 --- a/command.go +++ b/command.go @@ -1509,6 +1509,112 @@ func (cmd *XPendingExtCmd) readReply(rd *proto.Reader) error { //------------------------------------------------------------------------------ +type XAutoClaimCmd struct { + baseCmd + + start string + val []XMessage +} + +var _ Cmder = (*XAutoClaimCmd)(nil) + +func NewXAutoClaimCmd(ctx context.Context, args ...interface{}) *XAutoClaimCmd { + return &XAutoClaimCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *XAutoClaimCmd) Val() (messages []XMessage, start string) { + return cmd.val, cmd.start +} + +func (cmd *XAutoClaimCmd) Result() (messages []XMessage, start string, err error) { + return cmd.val, cmd.start, cmd.err +} + +func (cmd *XAutoClaimCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XAutoClaimCmd) readReply(rd *proto.Reader) error { + var err error + if err = rd.ReadFixedArrayLen(2); err != nil { + return err + } + + cmd.start, err = rd.ReadString() + if err != nil { + return err + } + cmd.val, err = readXMessageSlice(rd) + if err != nil { + return err + } + return nil +} + +//------------------------------------------------------------------------------ + +type XAutoClaimJustIDCmd struct { + baseCmd + + start string + val []string +} + +var _ Cmder = (*XAutoClaimJustIDCmd)(nil) + +func NewXAutoClaimJustIDCmd(ctx context.Context, args ...interface{}) *XAutoClaimJustIDCmd { + return &XAutoClaimJustIDCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + } +} + +func (cmd *XAutoClaimJustIDCmd) Val() (ids []string, start string) { + return cmd.val, cmd.start +} + +func (cmd *XAutoClaimJustIDCmd) Result() (ids []string, start string, err error) { + return cmd.val, cmd.start, cmd.err +} + +func (cmd *XAutoClaimJustIDCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *XAutoClaimJustIDCmd) readReply(rd *proto.Reader) error { + var err error + if err = rd.ReadFixedArrayLen(2); err != nil { + return err + } + + cmd.start, err = rd.ReadString() + if err != nil { + return err + } + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + + cmd.val = make([]string, n) + for i := 0; i < n; i++ { + cmd.val[i], err = rd.ReadString() + if err != nil { + return err + } + } + return nil +} + +//------------------------------------------------------------------------------ + type XInfoConsumersCmd struct { baseCmd val []XInfoConsumer diff --git a/commands.go b/commands.go index 540c3b59a3..423d6e808c 100644 --- a/commands.go +++ b/commands.go @@ -9,7 +9,8 @@ import ( "github.com/go-redis/redis/v8/internal" ) -// KeepTTL is an option for Set command to keep key's existing TTL. +// KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, +// otherwise you will receive an error: (error) ERR syntax error. // For example: // // rdb.Set(ctx, key, value, redis.KeepTTL) @@ -132,8 +133,7 @@ type Cmdable interface { MSetNX(ctx context.Context, values ...interface{}) *BoolCmd Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd SetArgs(ctx context.Context, key string, value interface{}, a SetArgs) *StatusCmd - // TODO: rename to SetEx - SetEX(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd + SetEx(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd SetRange(ctx context.Context, key string, offset int64, value string) *IntCmd @@ -227,6 +227,7 @@ type Cmdable interface { XGroupCreateMkStream(ctx context.Context, stream, group, start string) *StatusCmd XGroupSetID(ctx context.Context, stream, group, start string) *StatusCmd XGroupDestroy(ctx context.Context, stream, group string) *IntCmd + XGroupCreateConsumer(ctx context.Context, stream, group, consumer string) *IntCmd XGroupDelConsumer(ctx context.Context, stream, group, consumer string) *IntCmd XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSliceCmd XAck(ctx context.Context, stream, group string, ids ...string) *IntCmd @@ -234,23 +235,23 @@ type Cmdable interface { XPendingExt(ctx context.Context, a *XPendingExtArgs) *XPendingExtCmd XClaim(ctx context.Context, a *XClaimArgs) *XMessageSliceCmd XClaimJustID(ctx context.Context, a *XClaimArgs) *StringSliceCmd - XTrim(ctx context.Context, key string, maxLen int64) *IntCmd - XTrimApprox(ctx context.Context, key string, maxLen int64) *IntCmd + + XTrimMaxLen(ctx context.Context, key string, maxLen int64) *IntCmd + XTrimMaxLenApprox(ctx context.Context, key string, maxLen, limit int64) *IntCmd + XTrimMinID(ctx context.Context, key string, minID string) *IntCmd + XTrimMinIDApprox(ctx context.Context, key string, minID string, limit int64) *IntCmd XInfoGroups(ctx context.Context, key string) *XInfoGroupsCmd XInfoStream(ctx context.Context, key string) *XInfoStreamCmd XInfoConsumers(ctx context.Context, key string, group string) *XInfoConsumersCmd BZPopMax(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd BZPopMin(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd - ZAdd(ctx context.Context, key string, members ...*Z) *IntCmd - ZAddNX(ctx context.Context, key string, members ...*Z) *IntCmd - ZAddXX(ctx context.Context, key string, members ...*Z) *IntCmd - ZAddCh(ctx context.Context, key string, members ...*Z) *IntCmd - ZAddNXCh(ctx context.Context, key string, members ...*Z) *IntCmd - ZAddXXCh(ctx context.Context, key string, members ...*Z) *IntCmd - ZIncr(ctx context.Context, key string, member *Z) *FloatCmd - ZIncrNX(ctx context.Context, key string, member *Z) *FloatCmd - ZIncrXX(ctx context.Context, key string, member *Z) *FloatCmd + + ZAdd(ctx context.Context, key string, members ...Z) *IntCmd + ZAddNX(ctx context.Context, key string, members ...Z) *IntCmd + ZAddXX(ctx context.Context, key string, members ...Z) *IntCmd + ZAddArgs(ctx context.Context, key string, args ZAddArgs) *IntCmd + ZAddArgsIncr(ctx context.Context, key string, args ZAddArgs) *FloatCmd ZCard(ctx context.Context, key string) *IntCmd ZCount(ctx context.Context, key, min, max string) *IntCmd ZLexCount(ctx context.Context, key, min, max string) *IntCmd @@ -266,6 +267,9 @@ type Cmdable interface { ZRangeByScore(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd ZRangeByLex(ctx context.Context, key string, opt *ZRangeBy) *StringSliceCmd ZRangeByScoreWithScores(ctx context.Context, key string, opt *ZRangeBy) *ZSliceCmd + ZRangeArgs(ctx context.Context, z ZRangeArgs) *StringSliceCmd + ZRangeArgsWithScores(ctx context.Context, z ZRangeArgs) *ZSliceCmd + ZRangeStore(ctx context.Context, dst string, z ZRangeArgs) *IntCmd ZRank(ctx context.Context, key, member string) *IntCmd ZRem(ctx context.Context, key string, members ...interface{}) *IntCmd ZRemRangeByRank(ctx context.Context, key string, start, stop int64) *IntCmd @@ -281,6 +285,8 @@ type Cmdable interface { ZUnionStore(ctx context.Context, dest string, store *ZStore) *IntCmd ZRandMember(ctx context.Context, key string, count int) *StringSliceCmd ZRandMemberWithScores(ctx context.Context, key string, count int) *ZSliceCmd + ZUnion(ctx context.Context, store ZStore) *StringSliceCmd + ZUnionWithScores(ctx context.Context, store ZStore) *ZSliceCmd ZDiff(ctx context.Context, keys ...string) *StringSliceCmd ZDiffWithScores(ctx context.Context, keys ...string) *ZSliceCmd ZDiffStore(ctx context.Context, destination string, keys ...string) *IntCmd @@ -733,7 +739,7 @@ func (c cmdable) DecrBy(ctx context.Context, key string, decrement int64) *IntCm return cmd } -// Get redis `GET key` command. It returns redis.Nil error when key does not exist. +// Get Redis `GET key` command. It returns redis.Nil error when key does not exist. func (c cmdable) Get(ctx context.Context, key string) *StringCmd { cmd := NewStringCmd(ctx, "get", key) _ = c(ctx, cmd) @@ -835,10 +841,11 @@ func (c cmdable) MSetNX(ctx context.Context, values ...interface{}) *BoolCmd { } // Set Redis `SET key value [expiration]` command. -// Use expiration for `SETEX`-like behavior. +// Use expiration for `SETEx`-like behavior. // // Zero expiration means the key has no expiration time. -// KeepTTL(-1) expiration is a Redis KEEPTTL option to keep existing TTL. +// KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, +// otherwise you will receive an error: (error) ERR syntax error. func (c cmdable) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd { args := make([]interface{}, 3, 5) args[0] = "set" @@ -871,7 +878,8 @@ type SetArgs struct { // When Get is true, the command returns the old value stored at key, or nil when key did not exist. Get bool - // KeepTTL is a Redis KEEPTTL option to keep existing TTL. + // KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, + // otherwise you will receive an error: (error) ERR syntax error. KeepTTL bool } @@ -909,8 +917,8 @@ func (c cmdable) SetArgs(ctx context.Context, key string, value interface{}, a S return cmd } -// SetEX Redis `SETEX key expiration value` command. -func (c cmdable) SetEX(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd { +// SetEx Redis `SETEx key expiration value` command. +func (c cmdable) SetEx(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd { cmd := NewStatusCmd(ctx, "setex", key, formatSec(ctx, expiration), value) _ = c(ctx, cmd) return cmd @@ -919,7 +927,8 @@ func (c cmdable) SetEX(ctx context.Context, key string, value interface{}, expir // SetNX Redis `SET key value [expiration] NX` command. // // Zero expiration means the key has no expiration time. -// KeepTTL(-1) expiration is a Redis KEEPTTL option to keep existing TTL. +// KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, +// otherwise you will receive an error: (error) ERR syntax error. func (c cmdable) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd { var cmd *BoolCmd switch expiration { @@ -943,7 +952,8 @@ func (c cmdable) SetNX(ctx context.Context, key string, value interface{}, expir // SetXX Redis `SET key value [expiration] XX` command. // // Zero expiration means the key has no expiration time. -// KeepTTL(-1) expiration is a Redis KEEPTTL option to keep existing TTL. +// KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, +// otherwise you will receive an error: (error) ERR syntax error. func (c cmdable) SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd { var cmd *BoolCmd switch expiration { @@ -1643,22 +1653,44 @@ func (c cmdable) SUnionStore(ctx context.Context, destination string, keys ...st // - XAddArgs.Values = map[string]interface{}{"key1": "value1", "key2": "value2"} // // Note that map will not preserve the order of key-value pairs. +// MaxLen/MaxLenApprox and MinID are in conflict, only one of them can be used. type XAddArgs struct { - Stream string - MaxLen int64 // MAXLEN N - MaxLenApprox int64 // MAXLEN ~ N - ID string - Values interface{} + Stream string + NoMkStream bool + MaxLen int64 // MAXLEN N + MinID string + + // Approx causes MaxLen and MinID to use "~" matcher (instead of "="). + Approx bool + Limit int64 + ID string + Values interface{} } +// XAdd a.Limit has a bug, please confirm it and use it. +// issue: https://github.com/redis/redis/issues/9046 func (c cmdable) XAdd(ctx context.Context, a *XAddArgs) *StringCmd { - args := make([]interface{}, 0, 8) - args = append(args, "xadd") - args = append(args, a.Stream) - if a.MaxLen > 0 { - args = append(args, "maxlen", a.MaxLen) - } else if a.MaxLenApprox > 0 { - args = append(args, "maxlen", "~", a.MaxLenApprox) + args := make([]interface{}, 0, 11) + args = append(args, "xadd", a.Stream) + if a.NoMkStream { + args = append(args, "nomkstream") + } + switch { + case a.MaxLen > 0: + if a.Approx { + args = append(args, "maxlen", "~", a.MaxLen) + } else { + args = append(args, "maxlen", a.MaxLen) + } + case a.MinID != "": + if a.Approx { + args = append(args, "minid", "~", a.MinID) + } else { + args = append(args, "minid", a.MinID) + } + } + if a.Limit > 0 { + args = append(args, "limit", a.Limit) } if a.ID != "" { args = append(args, a.ID) @@ -1779,6 +1811,12 @@ func (c cmdable) XGroupDestroy(ctx context.Context, stream, group string) *IntCm return cmd } +func (c cmdable) XGroupCreateConsumer(ctx context.Context, stream, group, consumer string) *IntCmd { + cmd := NewIntCmd(ctx, "xgroup", "createconsumer", stream, group, consumer) + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) XGroupDelConsumer(ctx context.Context, stream, group, consumer string) *IntCmd { cmd := NewIntCmd(ctx, "xgroup", "delconsumer", stream, group, consumer) _ = c(ctx, cmd) @@ -1867,6 +1905,39 @@ func (c cmdable) XPendingExt(ctx context.Context, a *XPendingExtArgs) *XPendingE return cmd } +type XAutoClaimArgs struct { + Stream string + Group string + MinIdle time.Duration + Start string + Count int64 + Consumer string +} + +func (c cmdable) XAutoClaim(ctx context.Context, a *XAutoClaimArgs) *XAutoClaimCmd { + args := xAutoClaimArgs(ctx, a) + cmd := NewXAutoClaimCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) XAutoClaimJustID(ctx context.Context, a *XAutoClaimArgs) *XAutoClaimJustIDCmd { + args := xAutoClaimArgs(ctx, a) + args = append(args, "justid") + cmd := NewXAutoClaimJustIDCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func xAutoClaimArgs(ctx context.Context, a *XAutoClaimArgs) []interface{} { + args := make([]interface{}, 0, 9) + args = append(args, "xautoclaim", a.Stream, a.Group, a.Consumer, formatMs(ctx, a.MinIdle), a.Start) + if a.Count > 0 { + args = append(args, "count", a.Count) + } + return args +} + type XClaimArgs struct { Stream string Group string @@ -1903,16 +1974,53 @@ func xClaimArgs(a *XClaimArgs) []interface{} { return args } -func (c cmdable) XTrim(ctx context.Context, key string, maxLen int64) *IntCmd { - cmd := NewIntCmd(ctx, "xtrim", key, "maxlen", maxLen) +// xTrim If approx is true, add the "~" parameter, otherwise it is the default "=" (redis default). +// example: +// XTRIM key MAXLEN/MINID threshold LIMIT limit. +// XTRIM key MAXLEN/MINID ~ threshold LIMIT limit. +// The redis-server version is lower than 6.2, please set limit to 0. +func (c cmdable) xTrim( + ctx context.Context, key, strategy string, + approx bool, threshold interface{}, limit int64, +) *IntCmd { + args := make([]interface{}, 0, 7) + args = append(args, "xtrim", key, strategy) + if approx { + args = append(args, "~") + } + args = append(args, threshold) + if limit > 0 { + args = append(args, "limit", limit) + } + cmd := NewIntCmd(ctx, args...) _ = c(ctx, cmd) return cmd } -func (c cmdable) XTrimApprox(ctx context.Context, key string, maxLen int64) *IntCmd { - cmd := NewIntCmd(ctx, "xtrim", key, "maxlen", "~", maxLen) - _ = c(ctx, cmd) - return cmd +// XTrimMaxLen No `~` rules are used, `limit` cannot be used. +// cmd: XTRIM key MAXLEN maxLen +func (c cmdable) XTrimMaxLen(ctx context.Context, key string, maxLen int64) *IntCmd { + return c.xTrim(ctx, key, "maxlen", false, maxLen, 0) +} + +// XTrimMaxLenApprox LIMIT has a bug, please confirm it and use it. +// issue: https://github.com/redis/redis/issues/9046 +// cmd: XTRIM key MAXLEN ~ maxLen LIMIT limit +func (c cmdable) XTrimMaxLenApprox(ctx context.Context, key string, maxLen, limit int64) *IntCmd { + return c.xTrim(ctx, key, "maxlen", true, maxLen, limit) +} + +// XTrimMinID No `~` rules are used, `limit` cannot be used. +// cmd: XTRIM key MINID minID +func (c cmdable) XTrimMinID(ctx context.Context, key string, minID string) *IntCmd { + return c.xTrim(ctx, key, "minid", false, minID, 0) +} + +// XTrimMinIDApprox LIMIT has a bug, please confirm it and use it. +// issue: https://github.com/redis/redis/issues/9046 +// cmd: XTRIM key MINID ~ minID LIMIT limit +func (c cmdable) XTrimMinIDApprox(ctx context.Context, key string, minID string, limit int64) *IntCmd { + return c.xTrim(ctx, key, "minid", true, minID, limit) } func (c cmdable) XInfoConsumers(ctx context.Context, key string, group string) *XInfoConsumersCmd { @@ -1960,7 +2068,7 @@ type ZWithKey struct { Key string } -// ZStore is used as an arg to ZInterStore and ZUnionStore. +// ZStore is used as an arg to ZInter/ZInterStore and ZUnion/ZUnionStore. type ZStore struct { Keys []string Weights []float64 @@ -1968,7 +2076,7 @@ type ZStore struct { Aggregate string } -func (z *ZStore) len() (n int) { +func (z ZStore) len() (n int) { n = len(z.Keys) if len(z.Weights) > 0 { n += 1 + len(z.Weights) @@ -1979,6 +2087,22 @@ func (z *ZStore) len() (n int) { return n } +func (z ZStore) appendArgs(args []interface{}) []interface{} { + for _, key := range z.Keys { + args = append(args, key) + } + if len(z.Weights) > 0 { + args = append(args, "weights") + for _, weights := range z.Weights { + args = append(args, weights) + } + } + if z.Aggregate != "" { + args = append(args, "aggregate", z.Aggregate) + } + return args +} + // BZPopMax Redis `BZPOPMAX key [key ...] timeout` command. func (c cmdable) BZPopMax(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd { args := make([]interface{}, 1+len(keys)+1) @@ -2007,96 +2131,79 @@ func (c cmdable) BZPopMin(ctx context.Context, timeout time.Duration, keys ...st return cmd } -func (c cmdable) zAdd(ctx context.Context, a []interface{}, n int, members ...*Z) *IntCmd { - for i, m := range members { - a[n+2*i] = m.Score - a[n+2*i+1] = m.Member - } - cmd := NewIntCmd(ctx, a...) - _ = c(ctx, cmd) - return cmd -} - -// ZAdd Redis `ZADD key score member [score member ...]` command. -func (c cmdable) ZAdd(ctx context.Context, key string, members ...*Z) *IntCmd { - const n = 2 - a := make([]interface{}, n+2*len(members)) - a[0], a[1] = "zadd", key - return c.zAdd(ctx, a, n, members...) -} - -// ZAddNX Redis `ZADD key NX score member [score member ...]` command. -func (c cmdable) ZAddNX(ctx context.Context, key string, members ...*Z) *IntCmd { - const n = 3 - a := make([]interface{}, n+2*len(members)) - a[0], a[1], a[2] = "zadd", key, "nx" - return c.zAdd(ctx, a, n, members...) -} - -// ZAddXX Redis `ZADD key XX score member [score member ...]` command. -func (c cmdable) ZAddXX(ctx context.Context, key string, members ...*Z) *IntCmd { - const n = 3 - a := make([]interface{}, n+2*len(members)) - a[0], a[1], a[2] = "zadd", key, "xx" - return c.zAdd(ctx, a, n, members...) +// ZAddArgs WARN: The GT, LT and NX options are mutually exclusive. +type ZAddArgs struct { + NX bool + XX bool + LT bool + GT bool + Ch bool + Members []Z } -// ZAddCh Redis `ZADD key CH score member [score member ...]` command. -func (c cmdable) ZAddCh(ctx context.Context, key string, members ...*Z) *IntCmd { - const n = 3 - a := make([]interface{}, n+2*len(members)) - a[0], a[1], a[2] = "zadd", key, "ch" - return c.zAdd(ctx, a, n, members...) -} +func (c cmdable) zAddArgs(key string, args ZAddArgs, incr bool) []interface{} { + a := make([]interface{}, 0, 6+2*len(args.Members)) + a = append(a, "zadd", key) -// ZAddNXCh Redis `ZADD key NX CH score member [score member ...]` command. -func (c cmdable) ZAddNXCh(ctx context.Context, key string, members ...*Z) *IntCmd { - const n = 4 - a := make([]interface{}, n+2*len(members)) - a[0], a[1], a[2], a[3] = "zadd", key, "nx", "ch" - return c.zAdd(ctx, a, n, members...) + // The GT, LT and NX options are mutually exclusive. + if args.NX { + a = append(a, "nx") + } else { + if args.XX { + a = append(a, "xx") + } + if args.GT { + a = append(a, "gt") + } else if args.LT { + a = append(a, "lt") + } + } + if args.Ch { + a = append(a, "ch") + } + if incr { + a = append(a, "incr") + } + for _, m := range args.Members { + a = append(a, m.Score) + a = append(a, m.Member) + } + return a } -// ZAddXXCh Redis `ZADD key XX CH score member [score member ...]` command. -func (c cmdable) ZAddXXCh(ctx context.Context, key string, members ...*Z) *IntCmd { - const n = 4 - a := make([]interface{}, n+2*len(members)) - a[0], a[1], a[2], a[3] = "zadd", key, "xx", "ch" - return c.zAdd(ctx, a, n, members...) +func (c cmdable) ZAddArgs(ctx context.Context, key string, args ZAddArgs) *IntCmd { + cmd := NewIntCmd(ctx, c.zAddArgs(key, args, false)...) + _ = c(ctx, cmd) + return cmd } -func (c cmdable) zIncr(ctx context.Context, a []interface{}, n int, members ...*Z) *FloatCmd { - for i, m := range members { - a[n+2*i] = m.Score - a[n+2*i+1] = m.Member - } - cmd := NewFloatCmd(ctx, a...) +func (c cmdable) ZAddArgsIncr(ctx context.Context, key string, args ZAddArgs) *FloatCmd { + cmd := NewFloatCmd(ctx, c.zAddArgs(key, args, true)...) _ = c(ctx, cmd) return cmd } -// ZIncr Redis `ZADD key INCR score member` command. -func (c cmdable) ZIncr(ctx context.Context, key string, member *Z) *FloatCmd { - const n = 3 - a := make([]interface{}, n+2) - a[0], a[1], a[2] = "zadd", key, "incr" - return c.zIncr(ctx, a, n, member) +// ZAdd Redis `ZADD key score member [score member ...]` command. +func (c cmdable) ZAdd(ctx context.Context, key string, members ...Z) *IntCmd { + return c.ZAddArgs(ctx, key, ZAddArgs{ + Members: members, + }) } -// ZIncrNX Redis `ZADD key NX INCR score member` command. -func (c cmdable) ZIncrNX(ctx context.Context, key string, member *Z) *FloatCmd { - const n = 4 - a := make([]interface{}, n+2) - a[0], a[1], a[2], a[3] = "zadd", key, "incr", "nx" - return c.zIncr(ctx, a, n, member) +// ZAddNX Redis `ZADD key NX score member [score member ...]` command. +func (c cmdable) ZAddNX(ctx context.Context, key string, members ...Z) *IntCmd { + return c.ZAddArgs(ctx, key, ZAddArgs{ + NX: true, + Members: members, + }) } -// ZIncrXX Redis `ZADD key XX INCR score member` command. -func (c cmdable) ZIncrXX(ctx context.Context, key string, member *Z) *FloatCmd { - const n = 4 - a := make([]interface{}, n+2) - a[0], a[1], a[2], a[3] = "zadd", key, "incr", "xx" - return c.zIncr(ctx, a, n, member) +// ZAddXX Redis `ZADD key XX score member [score member ...]` command. +func (c cmdable) ZAddXX(ctx context.Context, key string, members ...Z) *IntCmd { + return c.ZAddArgs(ctx, key, ZAddArgs{ + XX: true, + Members: members, + }) } func (c cmdable) ZCard(ctx context.Context, key string) *IntCmd { @@ -2126,18 +2233,7 @@ func (c cmdable) ZIncrBy(ctx context.Context, key string, increment float64, mem func (c cmdable) ZInterStore(ctx context.Context, destination string, store *ZStore) *IntCmd { args := make([]interface{}, 0, 3+store.len()) args = append(args, "zinterstore", destination, len(store.Keys)) - for _, key := range store.Keys { - args = append(args, key) - } - if len(store.Weights) > 0 { - args = append(args, "weights") - for _, weight := range store.Weights { - args = append(args, weight) - } - } - if store.Aggregate != "" { - args = append(args, "aggregate", store.Aggregate) - } + args = store.appendArgs(args) cmd := NewIntCmd(ctx, args...) cmd.setFirstKeyPos(3) _ = c(ctx, cmd) @@ -2147,19 +2243,7 @@ func (c cmdable) ZInterStore(ctx context.Context, destination string, store *ZSt func (c cmdable) ZInter(ctx context.Context, store *ZStore) *StringSliceCmd { args := make([]interface{}, 0, 2+store.len()) args = append(args, "zinter", len(store.Keys)) - for _, key := range store.Keys { - args = append(args, key) - } - if len(store.Weights) > 0 { - args = append(args, "weights") - for _, weights := range store.Weights { - args = append(args, weights) - } - } - - if store.Aggregate != "" { - args = append(args, "aggregate", store.Aggregate) - } + args = store.appendArgs(args) cmd := NewStringSliceCmd(ctx, args...) cmd.setFirstKeyPos(2) _ = c(ctx, cmd) @@ -2169,18 +2253,7 @@ func (c cmdable) ZInter(ctx context.Context, store *ZStore) *StringSliceCmd { func (c cmdable) ZInterWithScores(ctx context.Context, store *ZStore) *ZSliceCmd { args := make([]interface{}, 0, 3+store.len()) args = append(args, "zinter", len(store.Keys)) - for _, key := range store.Keys { - args = append(args, key) - } - if len(store.Weights) > 0 { - args = append(args, "weights") - for _, weights := range store.Weights { - args = append(args, weights) - } - } - if store.Aggregate != "" { - args = append(args, "aggregate", store.Aggregate) - } + args = store.appendArgs(args) args = append(args, "withscores") cmd := NewZSliceCmd(ctx, args...) cmd.setFirstKeyPos(2) @@ -2240,29 +2313,112 @@ func (c cmdable) ZPopMin(ctx context.Context, key string, count ...int64) *ZSlic return cmd } -func (c cmdable) zRange(ctx context.Context, key string, start, stop int64, withScores bool) *StringSliceCmd { - args := []interface{}{ - "zrange", - key, - start, - stop, +// ZRangeArgs is all the options of the ZRange command. +// In version> 6.2.0, you can replace the(cmd): +// ZREVRANGE, +// ZRANGEBYSCORE, +// ZREVRANGEBYSCORE, +// ZRANGEBYLEX, +// ZREVRANGEBYLEX. +// Please pay attention to your redis-server version. +// +// Rev, ByScore, ByLex and Offset+Count options require redis-server 6.2.0 and higher. +type ZRangeArgs struct { + Key string + + // When the ByScore option is provided, the open interval(exclusive) can be set. + // By default, the score intervals specified by and are closed (inclusive). + // It is similar to the deprecated(6.2.0+) ZRangeByScore command. + // For example: + // ZRangeArgs{ + // Key: "example-key", + // Start: "(3", + // Stop: 8, + // ByScore: true, + // } + // cmd: "ZRange example-key (3 8 ByScore" (3 < score <= 8). + // + // For the ByLex option, it is similar to the deprecated(6.2.0+) ZRangeByLex command. + // You can set the and options as follows: + // ZRangeArgs{ + // Key: "example-key", + // Start: "[abc", + // Stop: "(def", + // ByLex: true, + // } + // cmd: "ZRange example-key [abc (def ByLex" + // + // For normal cases (ByScore==false && ByLex==false), and should be set to the index range (int). + // You can read the documentation for more information: https://redis.io/commands/zrange + Start interface{} + Stop interface{} + + // The ByScore and ByLex options are mutually exclusive. + ByScore bool + ByLex bool + + Rev bool + + // limit offset count. + Offset int64 + Count int64 +} + +func (z ZRangeArgs) appendArgs(args []interface{}) []interface{} { + // For Rev+ByScore/ByLex, we need to adjust the position of and . + if z.Rev && (z.ByScore || z.ByLex) { + args = append(args, z.Key, z.Stop, z.Start) + } else { + args = append(args, z.Key, z.Start, z.Stop) } - if withScores { - args = append(args, "withscores") + + if z.ByScore { + args = append(args, "byscore") + } else if z.ByLex { + args = append(args, "bylex") + } + if z.Rev { + args = append(args, "rev") + } + if z.Offset != 0 || z.Count != 0 { + args = append(args, "limit", z.Offset, z.Count) } + return args +} + +func (c cmdable) ZRangeArgs(ctx context.Context, z ZRangeArgs) *StringSliceCmd { + args := make([]interface{}, 0, 9) + args = append(args, "zrange") + args = z.appendArgs(args) cmd := NewStringSliceCmd(ctx, args...) _ = c(ctx, cmd) return cmd } +func (c cmdable) ZRangeArgsWithScores(ctx context.Context, z ZRangeArgs) *ZSliceCmd { + args := make([]interface{}, 0, 10) + args = append(args, "zrange") + args = z.appendArgs(args) + args = append(args, "withscores") + cmd := NewZSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) ZRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd { - return c.zRange(ctx, key, start, stop, false) + return c.ZRangeArgs(ctx, ZRangeArgs{ + Key: key, + Start: start, + Stop: stop, + }) } func (c cmdable) ZRangeWithScores(ctx context.Context, key string, start, stop int64) *ZSliceCmd { - cmd := NewZSliceCmd(ctx, "zrange", key, start, stop, "withscores") - _ = c(ctx, cmd) - return cmd + return c.ZRangeArgsWithScores(ctx, ZRangeArgs{ + Key: key, + Start: start, + Stop: stop, + }) } type ZRangeBy struct { @@ -2311,6 +2467,15 @@ func (c cmdable) ZRangeByScoreWithScores(ctx context.Context, key string, opt *Z return cmd } +func (c cmdable) ZRangeStore(ctx context.Context, dst string, z ZRangeArgs) *IntCmd { + args := make([]interface{}, 0, 10) + args = append(args, "zrangestore", dst) + args = z.appendArgs(args) + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) ZRank(ctx context.Context, key, member string) *IntCmd { cmd := NewIntCmd(ctx, "zrank", key, member) _ = c(ctx, cmd) @@ -2413,22 +2578,31 @@ func (c cmdable) ZScore(ctx context.Context, key, member string) *FloatCmd { return cmd } +func (c cmdable) ZUnion(ctx context.Context, store ZStore) *StringSliceCmd { + args := make([]interface{}, 0, 2+store.len()) + args = append(args, "zunion", len(store.Keys)) + args = store.appendArgs(args) + cmd := NewStringSliceCmd(ctx, args...) + cmd.setFirstKeyPos(2) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) ZUnionWithScores(ctx context.Context, store ZStore) *ZSliceCmd { + args := make([]interface{}, 0, 3+store.len()) + args = append(args, "zunion", len(store.Keys)) + args = store.appendArgs(args) + args = append(args, "withscores") + cmd := NewZSliceCmd(ctx, args...) + cmd.setFirstKeyPos(2) + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) ZUnionStore(ctx context.Context, dest string, store *ZStore) *IntCmd { args := make([]interface{}, 0, 3+store.len()) args = append(args, "zunionstore", dest, len(store.Keys)) - for _, key := range store.Keys { - args = append(args, key) - } - if len(store.Weights) > 0 { - args = append(args, "weights") - for _, weight := range store.Weights { - args = append(args, weight) - } - } - if store.Aggregate != "" { - args = append(args, "aggregate", store.Aggregate) - } - + args = store.appendArgs(args) cmd := NewIntCmd(ctx, args...) cmd.setFirstKeyPos(3) _ = c(ctx, cmd) diff --git a/commands_test.go b/commands_test.go index a47a5fb318..66f69a5a4b 100644 --- a/commands_test.go +++ b/commands_test.go @@ -827,7 +827,7 @@ var _ = Describe("Commands", func() { It("should ZScan", func() { for i := 0; i < 1000; i++ { - err := client.ZAdd(ctx, "myset", &redis.Z{ + err := client.ZAdd(ctx, "myset", redis.Z{ Score: float64(i), Member: fmt.Sprintf("member%d", i), }).Err() @@ -847,13 +847,13 @@ var _ = Describe("Commands", func() { Expect(err).NotTo(HaveOccurred()) Expect(n).To(Equal(int64(0))) - append := client.Append(ctx, "key", "Hello") - Expect(append.Err()).NotTo(HaveOccurred()) - Expect(append.Val()).To(Equal(int64(5))) + appendRes := client.Append(ctx, "key", "Hello") + Expect(appendRes.Err()).NotTo(HaveOccurred()) + Expect(appendRes.Val()).To(Equal(int64(5))) - append = client.Append(ctx, "key", " World") - Expect(append.Err()).NotTo(HaveOccurred()) - Expect(append.Val()).To(Equal(int64(11))) + appendRes = client.Append(ctx, "key", " World") + Expect(appendRes.Err()).NotTo(HaveOccurred()) + Expect(appendRes.Val()).To(Equal(int64(11))) get := client.Get(ctx, "key") Expect(get.Err()).NotTo(HaveOccurred()) @@ -1508,7 +1508,7 @@ var _ = Describe("Commands", func() { }) It("should SetEX", func() { - err := client.SetEX(ctx, "key", "hello", 1*time.Second).Err() + err := client.SetEx(ctx, "key", "hello", 1*time.Second).Err() Expect(err).NotTo(HaveOccurred()) val, err := client.Get(ctx, "key").Result() @@ -2705,17 +2705,17 @@ var _ = Describe("Commands", func() { Describe("sorted sets", func() { It("should BZPopMax", func() { - err := client.ZAdd(ctx, "zset1", &redis.Z{ + err := client.ZAdd(ctx, "zset1", redis.Z{ Score: 1, Member: "one", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{ + err = client.ZAdd(ctx, "zset1", redis.Z{ Score: 2, Member: "two", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{ + err = client.ZAdd(ctx, "zset1", redis.Z{ Score: 3, Member: "three", }).Err() @@ -2759,7 +2759,7 @@ var _ = Describe("Commands", func() { // ok } - zAdd := client.ZAdd(ctx, "zset", &redis.Z{ + zAdd := client.ZAdd(ctx, "zset", redis.Z{ Member: "a", Score: 1, }) @@ -2787,17 +2787,17 @@ var _ = Describe("Commands", func() { }) It("should BZPopMin", func() { - err := client.ZAdd(ctx, "zset1", &redis.Z{ + err := client.ZAdd(ctx, "zset1", redis.Z{ Score: 1, Member: "one", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{ + err = client.ZAdd(ctx, "zset1", redis.Z{ Score: 2, Member: "two", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{ + err = client.ZAdd(ctx, "zset1", redis.Z{ Score: 3, Member: "three", }).Err() @@ -2841,7 +2841,7 @@ var _ = Describe("Commands", func() { // ok } - zAdd := client.ZAdd(ctx, "zset", &redis.Z{ + zAdd := client.ZAdd(ctx, "zset", redis.Z{ Member: "a", Score: 1, }) @@ -2869,28 +2869,28 @@ var _ = Describe("Commands", func() { }) It("should ZAdd", func() { - added, err := client.ZAdd(ctx, "zset", &redis.Z{ + added, err := client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Result() Expect(err).NotTo(HaveOccurred()) Expect(added).To(Equal(int64(1))) - added, err = client.ZAdd(ctx, "zset", &redis.Z{ + added, err = client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "uno", }).Result() Expect(err).NotTo(HaveOccurred()) Expect(added).To(Equal(int64(1))) - added, err = client.ZAdd(ctx, "zset", &redis.Z{ + added, err = client.ZAdd(ctx, "zset", redis.Z{ Score: 2, Member: "two", }).Result() Expect(err).NotTo(HaveOccurred()) Expect(added).To(Equal(int64(1))) - added, err = client.ZAdd(ctx, "zset", &redis.Z{ + added, err = client.ZAdd(ctx, "zset", redis.Z{ Score: 3, Member: "two", }).Result() @@ -2912,28 +2912,28 @@ var _ = Describe("Commands", func() { }) It("should ZAdd bytes", func() { - added, err := client.ZAdd(ctx, "zset", &redis.Z{ + added, err := client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: []byte("one"), }).Result() Expect(err).NotTo(HaveOccurred()) Expect(added).To(Equal(int64(1))) - added, err = client.ZAdd(ctx, "zset", &redis.Z{ + added, err = client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: []byte("uno"), }).Result() Expect(err).NotTo(HaveOccurred()) Expect(added).To(Equal(int64(1))) - added, err = client.ZAdd(ctx, "zset", &redis.Z{ + added, err = client.ZAdd(ctx, "zset", redis.Z{ Score: 2, Member: []byte("two"), }).Result() Expect(err).NotTo(HaveOccurred()) Expect(added).To(Equal(int64(1))) - added, err = client.ZAdd(ctx, "zset", &redis.Z{ + added, err = client.ZAdd(ctx, "zset", redis.Z{ Score: 3, Member: []byte("two"), }).Result() @@ -2954,8 +2954,44 @@ var _ = Describe("Commands", func() { }})) }) - It("should ZAddNX", func() { - added, err := client.ZAddNX(ctx, "zset", &redis.Z{ + It("should ZAddArgsGTAndLT", func() { + // Test only the GT+LT options. + added, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + GT: true, + Members: []redis.Z{{Score: 1, Member: "one"}}, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(added).To(Equal(int64(1))) + + vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}})) + + added, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + GT: true, + Members: []redis.Z{{Score: 2, Member: "one"}}, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(added).To(Equal(int64(0))) + + vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}})) + + added, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + LT: true, + Members: []redis.Z{{Score: 1, Member: "one"}}, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(added).To(Equal(int64(0))) + + vals, err = client.ZRangeWithScores(ctx, "zset", 0, -1).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}})) + }) + + It("should ZAddArgsNX", func() { + added, err := client.ZAddNX(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Result() @@ -2966,7 +3002,7 @@ var _ = Describe("Commands", func() { Expect(err).NotTo(HaveOccurred()) Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}})) - added, err = client.ZAddNX(ctx, "zset", &redis.Z{ + added, err = client.ZAddNX(ctx, "zset", redis.Z{ Score: 2, Member: "one", }).Result() @@ -2978,8 +3014,8 @@ var _ = Describe("Commands", func() { Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}})) }) - It("should ZAddXX", func() { - added, err := client.ZAddXX(ctx, "zset", &redis.Z{ + It("should ZAddArgsXX", func() { + added, err := client.ZAddXX(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Result() @@ -2990,14 +3026,14 @@ var _ = Describe("Commands", func() { Expect(err).NotTo(HaveOccurred()) Expect(vals).To(BeEmpty()) - added, err = client.ZAdd(ctx, "zset", &redis.Z{ + added, err = client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Result() Expect(err).NotTo(HaveOccurred()) Expect(added).To(Equal(int64(1))) - added, err = client.ZAddXX(ctx, "zset", &redis.Z{ + added, err = client.ZAddXX(ctx, "zset", redis.Z{ Score: 2, Member: "one", }).Result() @@ -3009,26 +3045,33 @@ var _ = Describe("Commands", func() { Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}})) }) - It("should ZAddCh", func() { - changed, err := client.ZAddCh(ctx, "zset", &redis.Z{ - Score: 1, - Member: "one", + It("should ZAddArgsCh", func() { + changed, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + Ch: true, + Members: []redis.Z{ + {Score: 1, Member: "one"}, + }, }).Result() Expect(err).NotTo(HaveOccurred()) Expect(changed).To(Equal(int64(1))) - changed, err = client.ZAddCh(ctx, "zset", &redis.Z{ - Score: 1, - Member: "one", + changed, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + Ch: true, + Members: []redis.Z{ + {Score: 1, Member: "one"}, + }, }).Result() Expect(err).NotTo(HaveOccurred()) Expect(changed).To(Equal(int64(0))) }) - It("should ZAddNXCh", func() { - changed, err := client.ZAddNXCh(ctx, "zset", &redis.Z{ - Score: 1, - Member: "one", + It("should ZAddArgsNXCh", func() { + changed, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + NX: true, + Ch: true, + Members: []redis.Z{ + {Score: 1, Member: "one"}, + }, }).Result() Expect(err).NotTo(HaveOccurred()) Expect(changed).To(Equal(int64(1))) @@ -3037,9 +3080,12 @@ var _ = Describe("Commands", func() { Expect(err).NotTo(HaveOccurred()) Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}})) - changed, err = client.ZAddNXCh(ctx, "zset", &redis.Z{ - Score: 2, - Member: "one", + changed, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + NX: true, + Ch: true, + Members: []redis.Z{ + {Score: 2, Member: "one"}, + }, }).Result() Expect(err).NotTo(HaveOccurred()) Expect(changed).To(Equal(int64(0))) @@ -3052,10 +3098,13 @@ var _ = Describe("Commands", func() { }})) }) - It("should ZAddXXCh", func() { - changed, err := client.ZAddXXCh(ctx, "zset", &redis.Z{ - Score: 1, - Member: "one", + It("should ZAddArgsXXCh", func() { + changed, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + XX: true, + Ch: true, + Members: []redis.Z{ + {Score: 1, Member: "one"}, + }, }).Result() Expect(err).NotTo(HaveOccurred()) Expect(changed).To(Equal(int64(0))) @@ -3064,16 +3113,19 @@ var _ = Describe("Commands", func() { Expect(err).NotTo(HaveOccurred()) Expect(vals).To(BeEmpty()) - added, err := client.ZAdd(ctx, "zset", &redis.Z{ + added, err := client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Result() Expect(err).NotTo(HaveOccurred()) Expect(added).To(Equal(int64(1))) - changed, err = client.ZAddXXCh(ctx, "zset", &redis.Z{ - Score: 2, - Member: "one", + changed, err = client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + XX: true, + Ch: true, + Members: []redis.Z{ + {Score: 2, Member: "one"}, + }, }).Result() Expect(err).NotTo(HaveOccurred()) Expect(changed).To(Equal(int64(1))) @@ -3083,10 +3135,11 @@ var _ = Describe("Commands", func() { Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}})) }) - It("should ZIncr", func() { - score, err := client.ZIncr(ctx, "zset", &redis.Z{ - Score: 1, - Member: "one", + It("should ZAddArgsIncr", func() { + score, err := client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{ + Members: []redis.Z{ + {Score: 1, Member: "one"}, + }, }).Result() Expect(err).NotTo(HaveOccurred()) Expect(score).To(Equal(float64(1))) @@ -3095,9 +3148,10 @@ var _ = Describe("Commands", func() { Expect(err).NotTo(HaveOccurred()) Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}})) - score, err = client.ZIncr(ctx, "zset", &redis.Z{ - Score: 1, - Member: "one", + score, err = client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{ + Members: []redis.Z{ + {Score: 1, Member: "one"}, + }, }).Result() Expect(err).NotTo(HaveOccurred()) Expect(score).To(Equal(float64(2))) @@ -3107,10 +3161,12 @@ var _ = Describe("Commands", func() { Expect(vals).To(Equal([]redis.Z{{Score: 2, Member: "one"}})) }) - It("should ZIncrNX", func() { - score, err := client.ZIncrNX(ctx, "zset", &redis.Z{ - Score: 1, - Member: "one", + It("should ZAddArgsIncrNX", func() { + score, err := client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{ + NX: true, + Members: []redis.Z{ + {Score: 1, Member: "one"}, + }, }).Result() Expect(err).NotTo(HaveOccurred()) Expect(score).To(Equal(float64(1))) @@ -3119,9 +3175,11 @@ var _ = Describe("Commands", func() { Expect(err).NotTo(HaveOccurred()) Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}})) - score, err = client.ZIncrNX(ctx, "zset", &redis.Z{ - Score: 1, - Member: "one", + score, err = client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{ + NX: true, + Members: []redis.Z{ + {Score: 1, Member: "one"}, + }, }).Result() Expect(err).To(Equal(redis.Nil)) Expect(score).To(Equal(float64(0))) @@ -3131,10 +3189,12 @@ var _ = Describe("Commands", func() { Expect(vals).To(Equal([]redis.Z{{Score: 1, Member: "one"}})) }) - It("should ZIncrXX", func() { - score, err := client.ZIncrXX(ctx, "zset", &redis.Z{ - Score: 1, - Member: "one", + It("should ZAddArgsIncrXX", func() { + score, err := client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{ + XX: true, + Members: []redis.Z{ + {Score: 1, Member: "one"}, + }, }).Result() Expect(err).To(Equal(redis.Nil)) Expect(score).To(Equal(float64(0))) @@ -3143,16 +3203,18 @@ var _ = Describe("Commands", func() { Expect(err).NotTo(HaveOccurred()) Expect(vals).To(BeEmpty()) - added, err := client.ZAdd(ctx, "zset", &redis.Z{ + added, err := client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Result() Expect(err).NotTo(HaveOccurred()) Expect(added).To(Equal(int64(1))) - score, err = client.ZIncrXX(ctx, "zset", &redis.Z{ - Score: 1, - Member: "one", + score, err = client.ZAddArgsIncr(ctx, "zset", redis.ZAddArgs{ + XX: true, + Members: []redis.Z{ + {Score: 1, Member: "one"}, + }, }).Result() Expect(err).NotTo(HaveOccurred()) Expect(score).To(Equal(float64(2))) @@ -3163,12 +3225,12 @@ var _ = Describe("Commands", func() { }) It("should ZCard", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{ + err := client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 2, Member: "two", }).Err() @@ -3180,17 +3242,17 @@ var _ = Describe("Commands", func() { }) It("should ZCount", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{ + err := client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 2, Member: "two", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 3, Member: "three", }).Err() @@ -3210,12 +3272,12 @@ var _ = Describe("Commands", func() { }) It("should ZIncrBy", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{ + err := client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 2, Member: "two", }).Err() @@ -3237,22 +3299,22 @@ var _ = Describe("Commands", func() { }) It("should ZInterStore", func() { - err := client.ZAdd(ctx, "zset1", &redis.Z{ + err := client.ZAdd(ctx, "zset1", redis.Z{ Score: 1, Member: "one", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{ + err = client.ZAdd(ctx, "zset1", redis.Z{ Score: 2, Member: "two", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 1, Member: "one"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset3", &redis.Z{Score: 3, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset3", redis.Z{Score: 3, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) n, err := client.ZInterStore(ctx, "out", &redis.ZStore{ @@ -3279,11 +3341,11 @@ var _ = Describe("Commands", func() { Expect(zmScore.Val()).To(HaveLen(2)) Expect(zmScore.Val()[0]).To(Equal(float64(0))) - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) zmScore = client.ZMScore(ctx, "zset", "one", "three") @@ -3301,17 +3363,17 @@ var _ = Describe("Commands", func() { }) It("should ZPopMax", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{ + err := client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 2, Member: "two", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 3, Member: "three", }).Err() @@ -3325,7 +3387,7 @@ var _ = Describe("Commands", func() { }})) // adding back 3 - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 3, Member: "three", }).Err() @@ -3341,12 +3403,12 @@ var _ = Describe("Commands", func() { }})) // adding back 2 & 3 - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 3, Member: "three", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 2, Member: "two", }).Err() @@ -3366,17 +3428,17 @@ var _ = Describe("Commands", func() { }) It("should ZPopMin", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{ + err := client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 2, Member: "two", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 3, Member: "three", }).Err() @@ -3390,7 +3452,7 @@ var _ = Describe("Commands", func() { }})) // adding back 1 - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Err() @@ -3406,13 +3468,13 @@ var _ = Describe("Commands", func() { }})) // adding back 1 & 2 - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 1, Member: "one", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 2, Member: "two", }).Err() @@ -3433,11 +3495,11 @@ var _ = Describe("Commands", func() { }) It("should ZRange", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) zRange := client.ZRange(ctx, "zset", 0, -1) @@ -3454,11 +3516,11 @@ var _ = Describe("Commands", func() { }) It("should ZRangeWithScores", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) vals, err := client.ZRangeWithScores(ctx, "zset", 0, -1).Result() @@ -3489,12 +3551,74 @@ var _ = Describe("Commands", func() { }})) }) + It("should ZRangeArgs", func() { + added, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + Members: []redis.Z{ + {Score: 1, Member: "one"}, + {Score: 2, Member: "two"}, + {Score: 3, Member: "three"}, + {Score: 4, Member: "four"}, + }, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(added).To(Equal(int64(4))) + + zRange, err := client.ZRangeArgs(ctx, redis.ZRangeArgs{ + Key: "zset", + Start: 1, + Stop: 4, + ByScore: true, + Rev: true, + Offset: 1, + Count: 2, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(zRange).To(Equal([]string{"three", "two"})) + + zRange, err = client.ZRangeArgs(ctx, redis.ZRangeArgs{ + Key: "zset", + Start: "-", + Stop: "+", + ByLex: true, + Rev: true, + Offset: 2, + Count: 2, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(zRange).To(Equal([]string{"two", "one"})) + + zRange, err = client.ZRangeArgs(ctx, redis.ZRangeArgs{ + Key: "zset", + Start: "(1", + Stop: "(4", + ByScore: true, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(zRange).To(Equal([]string{"two", "three"})) + + // withScores. + zSlice, err := client.ZRangeArgsWithScores(ctx, redis.ZRangeArgs{ + Key: "zset", + Start: 1, + Stop: 4, + ByScore: true, + Rev: true, + Offset: 1, + Count: 2, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(zSlice).To(Equal([]redis.Z{ + {Score: 3, Member: "three"}, + {Score: 2, Member: "two"}, + })) + }) + It("should ZRangeByScore", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) zRangeByScore := client.ZRangeByScore(ctx, "zset", &redis.ZRangeBy{ @@ -3527,17 +3651,17 @@ var _ = Describe("Commands", func() { }) It("should ZRangeByLex", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{ + err := client.ZAdd(ctx, "zset", redis.Z{ Score: 0, Member: "a", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 0, Member: "b", }).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{ + err = client.ZAdd(ctx, "zset", redis.Z{ Score: 0, Member: "c", }).Err() @@ -3573,11 +3697,11 @@ var _ = Describe("Commands", func() { }) It("should ZRangeByScoreWithScoresMap", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) vals, err := client.ZRangeByScoreWithScores(ctx, "zset", &redis.ZRangeBy{ @@ -3624,12 +3748,41 @@ var _ = Describe("Commands", func() { Expect(vals).To(Equal([]redis.Z{})) }) + It("should ZRangeStore", func() { + added, err := client.ZAddArgs(ctx, "zset", redis.ZAddArgs{ + Members: []redis.Z{ + {Score: 1, Member: "one"}, + {Score: 2, Member: "two"}, + {Score: 3, Member: "three"}, + {Score: 4, Member: "four"}, + }, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(added).To(Equal(int64(4))) + + rangeStore, err := client.ZRangeStore(ctx, "new-zset", redis.ZRangeArgs{ + Key: "zset", + Start: 1, + Stop: 4, + ByScore: true, + Rev: true, + Offset: 1, + Count: 2, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(rangeStore).To(Equal(int64(2))) + + zRange, err := client.ZRange(ctx, "new-zset", 0, -1).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(zRange).To(Equal([]string{"two", "three"})) + }) + It("should ZRank", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) zRank := client.ZRank(ctx, "zset", "three") @@ -3642,11 +3795,11 @@ var _ = Describe("Commands", func() { }) It("should ZRem", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) zRem := client.ZRem(ctx, "zset", "two") @@ -3665,11 +3818,11 @@ var _ = Describe("Commands", func() { }) It("should ZRemRangeByRank", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) zRemRangeByRank := client.ZRemRangeByRank(ctx, "zset", 0, 1) @@ -3685,11 +3838,11 @@ var _ = Describe("Commands", func() { }) It("should ZRemRangeByScore", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) zRemRangeByScore := client.ZRemRangeByScore(ctx, "zset", "-inf", "(2") @@ -3708,7 +3861,7 @@ var _ = Describe("Commands", func() { }) It("should ZRemRangeByLex", func() { - zz := []*redis.Z{ + zz := []redis.Z{ {Score: 0, Member: "aaaa"}, {Score: 0, Member: "b"}, {Score: 0, Member: "c"}, @@ -3735,11 +3888,11 @@ var _ = Describe("Commands", func() { }) It("should ZRevRange", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) zRevRange := client.ZRevRange(ctx, "zset", 0, -1) @@ -3756,11 +3909,11 @@ var _ = Describe("Commands", func() { }) It("should ZRevRangeWithScoresMap", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) val, err := client.ZRevRangeWithScores(ctx, "zset", 0, -1).Result() @@ -3792,11 +3945,11 @@ var _ = Describe("Commands", func() { }) It("should ZRevRangeByScore", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) vals, err := client.ZRevRangeByScore( @@ -3816,11 +3969,11 @@ var _ = Describe("Commands", func() { }) It("should ZRevRangeByLex", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 0, Member: "a"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 0, Member: "a"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 0, Member: "b"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 0, Member: "b"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 0, Member: "c"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 0, Member: "c"}).Err() Expect(err).NotTo(HaveOccurred()) vals, err := client.ZRevRangeByLex( @@ -3840,11 +3993,11 @@ var _ = Describe("Commands", func() { }) It("should ZRevRangeByScoreWithScores", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) vals, err := client.ZRevRangeByScoreWithScores( @@ -3863,11 +4016,11 @@ var _ = Describe("Commands", func() { }) It("should ZRevRangeByScoreWithScoresMap", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) vals, err := client.ZRevRangeByScoreWithScores( @@ -3896,11 +4049,11 @@ var _ = Describe("Commands", func() { }) It("should ZRevRank", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) zRevRank := client.ZRevRank(ctx, "zset", "one") @@ -3913,25 +4066,64 @@ var _ = Describe("Commands", func() { }) It("should ZScore", func() { - zAdd := client.ZAdd(ctx, "zset", &redis.Z{Score: 1.001, Member: "one"}) + zAdd := client.ZAdd(ctx, "zset", redis.Z{Score: 1.001, Member: "one"}) Expect(zAdd.Err()).NotTo(HaveOccurred()) zScore := client.ZScore(ctx, "zset", "one") Expect(zScore.Err()).NotTo(HaveOccurred()) - Expect(zScore.Val()).To(Equal(float64(1.001))) + Expect(zScore.Val()).To(Equal(1.001)) + }) + + It("should ZUnion", func() { + err := client.ZAddArgs(ctx, "zset1", redis.ZAddArgs{ + Members: []redis.Z{ + {Score: 1, Member: "one"}, + {Score: 2, Member: "two"}, + }, + }).Err() + Expect(err).NotTo(HaveOccurred()) + + err = client.ZAddArgs(ctx, "zset2", redis.ZAddArgs{ + Members: []redis.Z{ + {Score: 1, Member: "one"}, + {Score: 2, Member: "two"}, + {Score: 3, Member: "three"}, + }, + }).Err() + Expect(err).NotTo(HaveOccurred()) + + union, err := client.ZUnion(ctx, redis.ZStore{ + Keys: []string{"zset1", "zset2"}, + Weights: []float64{2, 3}, + Aggregate: "sum", + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(union).To(Equal([]string{"one", "three", "two"})) + + unionScores, err := client.ZUnionWithScores(ctx, redis.ZStore{ + Keys: []string{"zset1", "zset2"}, + Weights: []float64{2, 3}, + Aggregate: "sum", + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(unionScores).To(Equal([]redis.Z{ + {Score: 5, Member: "one"}, + {Score: 9, Member: "three"}, + {Score: 10, Member: "two"}, + })) }) It("should ZUnionStore", func() { - err := client.ZAdd(ctx, "zset1", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 1, Member: "one"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) n, err := client.ZUnionStore(ctx, "out", &redis.ZStore{ @@ -3956,9 +4148,9 @@ var _ = Describe("Commands", func() { }) It("should ZRandMember", func() { - err := client.ZAdd(ctx, "zset", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) v := client.ZRandMember(ctx, "zset", 1) @@ -3978,13 +4170,13 @@ var _ = Describe("Commands", func() { }) It("should ZDiff", func() { - err := client.ZAdd(ctx, "zset1", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset1", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 1, Member: "one"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) v, err := client.ZDiff(ctx, "zset1", "zset2").Result() @@ -3993,13 +4185,13 @@ var _ = Describe("Commands", func() { }) It("should ZDiffWithScores", func() { - err := client.ZAdd(ctx, "zset1", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset1", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 1, Member: "one"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) v, err := client.ZDiffWithScores(ctx, "zset1", "zset2").Result() @@ -4017,15 +4209,15 @@ var _ = Describe("Commands", func() { }) It("should ZInter", func() { - err := client.ZAdd(ctx, "zset1", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 1, Member: "one"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) v, err := client.ZInter(ctx, &redis.ZStore{ @@ -4036,15 +4228,15 @@ var _ = Describe("Commands", func() { }) It("should ZInterWithScores", func() { - err := client.ZAdd(ctx, "zset1", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 1, Member: "one"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) v, err := client.ZInterWithScores(ctx, &redis.ZStore{ @@ -4066,15 +4258,15 @@ var _ = Describe("Commands", func() { }) It("should ZDiffStore", func() { - err := client.ZAdd(ctx, "zset1", &redis.Z{Score: 1, Member: "one"}).Err() + err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset1", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset1", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 1, Member: "one"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 2, Member: "two"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 2, Member: "two"}).Err() Expect(err).NotTo(HaveOccurred()) - err = client.ZAdd(ctx, "zset2", &redis.Z{Score: 3, Member: "three"}).Err() + err = client.ZAdd(ctx, "zset2", redis.Z{Score: 3, Member: "three"}).Err() Expect(err).NotTo(HaveOccurred()) v, err := client.ZDiffStore(ctx, "out1", "zset1", "zset2").Result() Expect(err).NotTo(HaveOccurred()) @@ -4120,14 +4312,29 @@ var _ = Describe("Commands", func() { Expect(id).To(Equal("3-0")) }) - It("should XTrim", func() { - n, err := client.XTrim(ctx, "stream", 0).Result() + // TODO XTrimMaxLenApprox/XTrimMinIDApprox There is a bug in the limit parameter. + // TODO Don't test it for now. + // TODO link: https://github.com/redis/redis/issues/9046 + It("should XTrimMaxLen", func() { + n, err := client.XTrimMaxLen(ctx, "stream", 0).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(n).To(Equal(int64(3))) + }) + + It("should XTrimMaxLenApprox", func() { + n, err := client.XTrimMaxLenApprox(ctx, "stream", 0, 0).Result() Expect(err).NotTo(HaveOccurred()) Expect(n).To(Equal(int64(3))) }) - It("should XTrimApprox", func() { - n, err := client.XTrimApprox(ctx, "stream", 0).Result() + It("should XTrimMinID", func() { + n, err := client.XTrimMinID(ctx, "stream", "4-0").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(n).To(Equal(int64(3))) + }) + + It("should XTrimMinIDApprox", func() { + n, err := client.XTrimMinIDApprox(ctx, "stream", "4-0", 0).Result() Expect(err).NotTo(HaveOccurred()) Expect(n).To(Equal(int64(3))) }) @@ -4149,6 +4356,9 @@ var _ = Describe("Commands", func() { })) }) + // TODO XAdd There is a bug in the limit parameter. + // TODO Don't test it for now. + // TODO link: https://github.com/redis/redis/issues/9046 It("should XAdd with MaxLen", func() { id, err := client.XAdd(ctx, &redis.XAddArgs{ Stream: "stream", @@ -4164,6 +4374,21 @@ var _ = Describe("Commands", func() { })) }) + It("should XAdd with MinID", func() { + id, err := client.XAdd(ctx, &redis.XAddArgs{ + Stream: "stream", + MinID: "5-0", + ID: "4-0", + Values: map[string]interface{}{"quatro": "quatre"}, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(id).To(Equal("4-0")) + + vals, err := client.XRange(ctx, "stream", "-", "+").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(vals).To(HaveLen(0)) + }) + It("should XDel", func() { n, err := client.XDel(ctx, "stream", "1-0", "2-0", "3-0").Result() Expect(err).NotTo(HaveOccurred()) @@ -4396,12 +4621,55 @@ var _ = Describe("Commands", func() { infoExt, err = client.XPendingExt(ctx, args).Result() Expect(err).NotTo(HaveOccurred()) Expect(infoExt).To(HaveLen(0)) + }) - n, err := client.XGroupDelConsumer(ctx, "stream", "group", "consumer").Result() + It("should XGroup Create Delete Consumer", func() { + n, err := client.XGroupCreateConsumer(ctx, "stream", "group", "c1").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(n).To(Equal(int64(1))) + + n, err = client.XGroupDelConsumer(ctx, "stream", "group", "consumer").Result() Expect(err).NotTo(HaveOccurred()) Expect(n).To(Equal(int64(3))) }) + It("should XAutoClaim", func() { + xca := &redis.XAutoClaimArgs{ + Stream: "stream", + Group: "group", + Consumer: "consumer", + Start: "-", + Count: 2, + } + msgs, start, err := client.XAutoClaim(ctx, xca).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(start).To(Equal("2-0")) + Expect(msgs).To(Equal([]redis.XMessage{{ + ID: "1-0", + Values: map[string]interface{}{"uno": "un"}, + }, { + ID: "2-0", + Values: map[string]interface{}{"dos": "deux"}, + }})) + + xca.Start = start + msgs, start, err = client.XAutoClaim(ctx, xca).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(start).To(Equal("3-0")) + Expect(msgs).To(Equal([]redis.XMessage{{ + ID: "2-0", + Values: map[string]interface{}{"dos": "deux"}, + }, { + ID: "3-0", + Values: map[string]interface{}{"tres": "troix"}, + }})) + + ids, start, err := client.XAutoClaimJustID(ctx, xca).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(start).To(Equal("3-0")) + Expect(ids).To(Equal([]string{"2-0", "3-0"})) + }) + It("should XClaim", func() { msgs, err := client.XClaim(ctx, &redis.XClaimArgs{ Stream: "stream", @@ -4898,7 +5166,7 @@ var _ = Describe("Commands", func() { {nil, "", nil}, {"hello", "hello", new(string)}, {[]byte("hello"), "hello", new([]byte)}, - {int(1), "1", new(int)}, + {1, "1", new(int)}, {int8(1), "1", new(int8)}, {int16(1), "1", new(int16)}, {int32(1), "1", new(int32)}, @@ -4909,7 +5177,7 @@ var _ = Describe("Commands", func() { {uint32(1), "1", new(uint32)}, {uint64(1), "1", new(uint64)}, {float32(1.0), "1", new(float32)}, - {float64(1.0), "1", new(float64)}, + {1.0, "1", new(float64)}, {true, "1", new(bool)}, {false, "0", new(bool)}, } diff --git a/example_test.go b/example_test.go index 73b2f2d6e8..7e042758fd 100644 --- a/example_test.go +++ b/example_test.go @@ -188,8 +188,8 @@ func ExampleClient_Set() { } } -func ExampleClient_SetEX() { - err := rdb.SetEX(ctx, "key", "value", time.Hour).Err() +func ExampleClient_SetEx() { + err := rdb.SetEx(ctx, "key", "value", time.Hour).Err() if err != nil { panic(err) } diff --git a/go.mod b/go.mod index 4fb27a8fee..0b2ed13104 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,5 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f github.com/onsi/ginkgo v1.15.0 github.com/onsi/gomega v1.10.5 - go.opentelemetry.io/otel v0.20.0 go.opentelemetry.io/otel/metric v0.20.0 - go.opentelemetry.io/otel/trace v0.20.0 ) diff --git a/internal/hscan/hscan.go b/internal/hscan/hscan.go index 6f97f9287c..852c8bd525 100644 --- a/internal/hscan/hscan.go +++ b/internal/hscan/hscan.go @@ -49,7 +49,7 @@ var ( func Struct(dst interface{}) (StructValue, error) { v := reflect.ValueOf(dst) - // The dstination to scan into should be a struct pointer. + // The destination to scan into should be a struct pointer. if v.Kind() != reflect.Ptr || v.IsNil() { return StructValue{}, fmt.Errorf("redis.Scan(non-pointer %T)", dst) } diff --git a/internal/pool/conn.go b/internal/pool/conn.go index ee064c9fc9..1ce29edd4b 100644 --- a/internal/pool/conn.go +++ b/internal/pool/conn.go @@ -65,26 +65,17 @@ func (cn *Conn) RemoteAddr() net.Addr { } func (cn *Conn) WithReader(ctx context.Context, timeout time.Duration, fn func(rd *proto.Reader) error) error { - ctx, span := internal.StartSpan(ctx, "redis.with_reader") - defer span.End() - if err := cn.netConn.SetReadDeadline(cn.deadline(ctx, timeout)); err != nil { - return internal.RecordError(ctx, span, err) - } - if err := fn(cn.rd); err != nil { - return internal.RecordError(ctx, span, err) + return err } - return nil + return fn(cn.rd) } func (cn *Conn) WithWriter( ctx context.Context, timeout time.Duration, fn func(wr *proto.Writer) error, ) error { - ctx, span := internal.StartSpan(ctx, "redis.with_writer") - defer span.End() - if err := cn.netConn.SetWriteDeadline(cn.deadline(ctx, timeout)); err != nil { - return internal.RecordError(ctx, span, err) + return err } if cn.bw.Buffered() > 0 { @@ -92,11 +83,11 @@ func (cn *Conn) WithWriter( } if err := fn(cn.wr); err != nil { - return internal.RecordError(ctx, span, err) + return err } if err := cn.bw.Flush(); err != nil { - return internal.RecordError(ctx, span, err) + return err } internal.WritesCounter.Add(ctx, 1) diff --git a/internal/util.go b/internal/util.go index 1a648fe63c..e34a7f0326 100644 --- a/internal/util.go +++ b/internal/util.go @@ -4,16 +4,10 @@ import ( "context" "time" - "github.com/go-redis/redis/v8/internal/proto" "github.com/go-redis/redis/v8/internal/util" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/trace" ) func Sleep(ctx context.Context, dur time.Duration) error { - _, span := StartSpan(ctx, "time.Sleep") - defer span.End() - t := time.NewTimer(dur) defer t.Stop() @@ -50,21 +44,3 @@ func isLower(s string) bool { } return true } - -//------------------------------------------------------------------------------ - -var tracer = otel.Tracer("github.com/go-redis/redis") - -func StartSpan(ctx context.Context, name string) (context.Context, trace.Span) { - if span := trace.SpanFromContext(ctx); !span.IsRecording() { - return ctx, span - } - return tracer.Start(ctx, name) -} - -func RecordError(ctx context.Context, span trace.Span, err error) error { - if err != proto.Nil { - span.RecordError(err) - } - return err -} diff --git a/options.go b/options.go index 0fd8e880af..7cf1bc1bbf 100644 --- a/options.go +++ b/options.go @@ -12,9 +12,7 @@ import ( "strings" "time" - "github.com/go-redis/redis/v8/internal" "github.com/go-redis/redis/v8/internal/pool" - "go.opentelemetry.io/otel/attribute" ) // Limiter is the interface of a rate limiter or a circuit breaker. @@ -291,21 +289,7 @@ func getUserPassword(u *url.URL) (string, string) { func newConnPool(opt *Options) *pool.ConnPool { return pool.NewConnPool(&pool.Options{ Dialer: func(ctx context.Context) (net.Conn, error) { - ctx, span := internal.StartSpan(ctx, "redis.dial") - defer span.End() - - if span.IsRecording() { - span.SetAttributes( - attribute.String("db.connection_string", opt.Addr), - ) - } - - cn, err := opt.Dialer(ctx, opt.Network, opt.Addr) - if err != nil { - return nil, internal.RecordError(ctx, span, err) - } - - return cn, nil + return opt.Dialer(ctx, opt.Network, opt.Addr) }, PoolSize: opt.PoolSize, MinIdleConns: opt.MinIdleConns, diff --git a/redis.go b/redis.go index cce5fb9267..2673e84ba3 100644 --- a/redis.go +++ b/redis.go @@ -10,7 +10,6 @@ import ( "github.com/go-redis/redis/v8/internal" "github.com/go-redis/redis/v8/internal/pool" "github.com/go-redis/redis/v8/internal/proto" - "go.opentelemetry.io/otel/attribute" ) // Nil reply returned by Redis when key does not exist. @@ -230,17 +229,18 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { } cn.Inited = true - ctx, span := internal.StartSpan(ctx, "redis.init_conn") - defer span.End() - connPool := pool.NewSingleConnPool(c.connPool, cn) conn := newConn(ctx, c.opt, connPool) var auth bool // The low version of redis-server does not support the hello command. - if conn.Hello(ctx, 3, c.opt.Username, c.opt.Password, "").Err() == nil { + // For redis-server (<6.0) that does not support the Hello command, + // we continue to provide services with RESP2. + if err := conn.Hello(ctx, 3, c.opt.Username, c.opt.Password, "").Err(); err == nil { auth = true + } else if err.Error() != "ERR unknown command 'hello'" { + return err } _, err := conn.Pipelined(ctx, func(pipe Pipeliner) error { @@ -287,20 +287,11 @@ func (c *baseClient) releaseConn(ctx context.Context, cn *pool.Conn, err error) func (c *baseClient) withConn( ctx context.Context, fn func(context.Context, *pool.Conn) error, ) error { - ctx, span := internal.StartSpan(ctx, "redis.with_conn") - defer span.End() - cn, err := c.getConn(ctx) if err != nil { return err } - if span.IsRecording() { - if remoteAddr := cn.RemoteAddr(); remoteAddr != nil { - span.SetAttributes(attribute.String("net.peer.ip", remoteAddr.String())) - } - } - defer func() { c.releaseConn(ctx, cn, err) }() From 916da5b2ce5874f5dff788aef4ce49b8c3f44fac Mon Sep 17 00:00:00 2001 From: monkey92t Date: Fri, 2 Jul 2021 20:56:25 +0800 Subject: [PATCH 009/621] sync v8.11.0 --- CHANGELOG.md | 5 +++++ README.md | 7 +++++-- cluster.go | 2 +- commands.go | 4 ++-- extra/redisotel/example/go.mod | 8 +++++--- extra/redisotel/example/go.sum | 36 +++++++++++++++++++-------------- extra/redisotel/example/main.go | 4 ++-- extra/redisotel/go.mod | 4 ++-- go.mod | 2 +- go.sum | 21 ++----------------- internal/instruments.go | 33 ------------------------------ internal/pool/conn.go | 9 +-------- internal/pool/pool.go | 1 - options.go | 4 ++-- redis.go | 2 +- 15 files changed, 50 insertions(+), 92 deletions(-) delete mode 100644 internal/instruments.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 42d89b720e..63aabd3d97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ > :heart: > [**Uptrace.dev** - All-in-one tool to optimize performance and monitor errors & logs](https://uptrace.dev) +## v8.11 + +- Remove OpenTelemetry metrics. +- Supports more redis commands and options. + ## v8.10 - Removed extra OpenTelemetry spans from go-redis core. Now go-redis instrumentation only adds a diff --git a/README.md b/README.md index 5f52a55243..bc4624e0a9 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,11 @@ - [Examples](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#pkg-examples) - [RealWorld example app](https://github.com/uptrace/go-treemux-realworld-example-app) -> :heart: Please check [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, -> MySQL, and SQLite. +My other projects: + +- [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite. +- [treemux](https://github.com/vmihailenco/treemux) - high-speed, flexible, tree-based HTTP router + for Go. ## Ecosystem diff --git a/cluster.go b/cluster.go index 738d50a4e5..95d6585beb 100644 --- a/cluster.go +++ b/cluster.go @@ -91,7 +91,7 @@ func (opt *ClusterOptions) init() { } if opt.PoolSize == 0 { - opt.PoolSize = 5 * runtime.NumCPU() + opt.PoolSize = 5 * runtime.GOMAXPROCS(0) } switch opt.ReadTimeout { diff --git a/commands.go b/commands.go index 423d6e808c..57ff0d0de7 100644 --- a/commands.go +++ b/commands.go @@ -235,7 +235,8 @@ type Cmdable interface { XPendingExt(ctx context.Context, a *XPendingExtArgs) *XPendingExtCmd XClaim(ctx context.Context, a *XClaimArgs) *XMessageSliceCmd XClaimJustID(ctx context.Context, a *XClaimArgs) *StringSliceCmd - + XAutoClaim(ctx context.Context, a *XAutoClaimArgs) *XAutoClaimCmd + XAutoClaimJustID(ctx context.Context, a *XAutoClaimArgs) *XAutoClaimJustIDCmd XTrimMaxLen(ctx context.Context, key string, maxLen int64) *IntCmd XTrimMaxLenApprox(ctx context.Context, key string, maxLen, limit int64) *IntCmd XTrimMinID(ctx context.Context, key string, minID string) *IntCmd @@ -1659,7 +1660,6 @@ type XAddArgs struct { NoMkStream bool MaxLen int64 // MAXLEN N MinID string - // Approx causes MaxLen and MinID to use "~" matcher (instead of "="). Approx bool Limit int64 diff --git a/extra/redisotel/example/go.mod b/extra/redisotel/example/go.mod index b621aab545..1cbaf7fe98 100644 --- a/extra/redisotel/example/go.mod +++ b/extra/redisotel/example/go.mod @@ -4,7 +4,9 @@ go 1.16 require ( github.com/go-redis/redis/extra/redisotel/v8 v8.8.2 - go.opentelemetry.io/otel v0.19.0 - go.opentelemetry.io/otel/exporters/stdout v0.19.0 - go.opentelemetry.io/otel/sdk v0.19.0 + github.com/go-redis/redis/v8 v8.8.2 + go.opentelemetry.io/otel v1.0.0-RC1 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.0-RC1 + go.opentelemetry.io/otel/sdk v1.0.0-RC1 + go.opentelemetry.io/otel/sdk/metric v0.21.0 ) diff --git a/extra/redisotel/example/go.sum b/extra/redisotel/example/go.sum index 59284e5056..4e05e032a0 100644 --- a/extra/redisotel/example/go.sum +++ b/extra/redisotel/example/go.sum @@ -1,5 +1,4 @@ -github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg= -github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= @@ -27,8 +26,9 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -50,22 +50,28 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/otel v0.15.0/go.mod h1:e4GKElweB8W2gWUqbghw0B8t5MCTccc9212eNHnOHwA= -go.opentelemetry.io/otel v0.19.0 h1:Lenfy7QHRXPZVsw/12CWpxX6d/JkrX8wrx2vO8G80Ng= go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg= -go.opentelemetry.io/otel/exporters/stdout v0.19.0 h1:6+QJvepCJ/YS3rOlsnjhVo527ohlPowOBgsZThR9Hoc= -go.opentelemetry.io/otel/exporters/stdout v0.19.0/go.mod h1:UI2JnNRaSt9ChIHkk4+uqieH27qKt9isV9e2qRorCtg= -go.opentelemetry.io/otel/metric v0.19.0 h1:dtZ1Ju44gkJkYvo+3qGqVXmf88tc+a42edOywypengg= +go.opentelemetry.io/otel v1.0.0-RC1 h1:4CeoX93DNTWt8awGK9JmNXzF9j7TyOu9upscEdtcdXc= +go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.0-RC1 h1:SEfJImgKQ5TP2aTJwN08qhS8oFlYWr/neECGsyuxKWg= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.0-RC1/go.mod h1:TAM/UYjVd1UdaifWkof3qj9cCW9oINemHfj0K6yodSo= +go.opentelemetry.io/otel/internal/metric v0.21.0 h1:gZlIBo5O51hZOOZz8vEcuRx/l5dnADadKfpT70AELoo= +go.opentelemetry.io/otel/internal/metric v0.21.0/go.mod h1:iOfAaY2YycsXfYD4kaRSbLx2LKmfpKObWBEv9QK5zFo= go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc= -go.opentelemetry.io/otel/oteltest v0.19.0 h1:YVfA0ByROYqTwOxqHVZYZExzEpfZor+MU1rU+ip2v9Q= +go.opentelemetry.io/otel/metric v0.21.0 h1:ZtcJlHqVE4l8Su0WOLOd9fEPheJuYEiQ0wr9wv2p25I= +go.opentelemetry.io/otel/metric v0.21.0/go.mod h1:JWCt1bjivC4iCrz/aCrM1GSw+ZcvY44KCbaeeRhzHnc= go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA= -go.opentelemetry.io/otel/sdk v0.19.0 h1:13pQquZyGbIvGxBWcVzUqe8kg5VGbTBiKKKXpYCylRM= -go.opentelemetry.io/otel/sdk v0.19.0/go.mod h1:ouO7auJYMivDjywCHA6bqTI7jJMVQV1HdKR5CmH8DGo= -go.opentelemetry.io/otel/sdk/export/metric v0.19.0 h1:9A1PC2graOx3epRLRWbq4DPCdpMUYK8XeCrdAg6ycbI= -go.opentelemetry.io/otel/sdk/export/metric v0.19.0/go.mod h1:exXalzlU6quLTXiv29J+Qpj/toOzL3H5WvpbbjouTBo= -go.opentelemetry.io/otel/sdk/metric v0.19.0 h1:fka1Zc/lpRMS+KlTP/TRXZuaFtSjUg/maHV3U8rt1Mc= -go.opentelemetry.io/otel/sdk/metric v0.19.0/go.mod h1:t12+Mqmj64q1vMpxHlCGXGggo0sadYxEG6U+Us/9OA4= -go.opentelemetry.io/otel/trace v0.19.0 h1:1ucYlenXIDA1OlHVLDZKX0ObXV5RLaq06DtUKz5e5zc= +go.opentelemetry.io/otel/oteltest v1.0.0-RC1 h1:G685iP3XiskCwk/z0eIabL55XUl2gk0cljhGk9sB0Yk= +go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4= +go.opentelemetry.io/otel/sdk v1.0.0-RC1 h1:Sy2VLOOg24bipyC29PhuMXYNJrLsxkie8hyI7kUlG9Q= +go.opentelemetry.io/otel/sdk v1.0.0-RC1/go.mod h1:kj6yPn7Pgt5ByRuwesbaWcRLA+V7BSDg3Hf8xRvsvf8= +go.opentelemetry.io/otel/sdk/export/metric v0.21.0 h1:4tSMVkDbvrowOeP/6rOfGABEWv5n+0gCfhI/TWleUvc= +go.opentelemetry.io/otel/sdk/export/metric v0.21.0/go.mod h1:gTaOMSQmL4zfsTL47desIPbPla5MyMG29lN3PzcibVg= +go.opentelemetry.io/otel/sdk/metric v0.21.0 h1:LNLUj35NNdEpyJQwj/htiEsfnY6GeTIwYHweCJNV+nc= +go.opentelemetry.io/otel/sdk/metric v0.21.0/go.mod h1:OHOcF8ZjE/L8oL/QXpUFWklPwtaukrfHgoAiPek53rQ= go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg= +go.opentelemetry.io/otel/trace v1.0.0-RC1 h1:jrjqKJZEibFrDz+umEASeU3LvdVyWKlnTh7XEfwrT58= +go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/extra/redisotel/example/main.go b/extra/redisotel/example/main.go index 8853ee0091..335eb8f27c 100644 --- a/extra/redisotel/example/main.go +++ b/extra/redisotel/example/main.go @@ -6,14 +6,14 @@ import ( "github.com/go-redis/redis/extra/redisotel/v8" "github.com/go-redis/redis/v8" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/exporters/stdout" + stdoutexporter "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" sdktrace "go.opentelemetry.io/otel/sdk/trace" ) var tracer = otel.Tracer("app_or_package_name") func main() { - exporter, err := stdout.NewExporter(stdout.WithPrettyPrint()) + exporter, err := stdoutexporter.New(stdoutexporter.WithPrettyPrint()) if err != nil { panic(err) } diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod index 9e601388de..28ba2d98ae 100644 --- a/extra/redisotel/go.mod +++ b/extra/redisotel/go.mod @@ -9,6 +9,6 @@ replace github.com/go-redis/redis/extra/rediscmd/v8 => ../rediscmd require ( github.com/go-redis/redis/extra/rediscmd/v8 v8.8.2 github.com/go-redis/redis/v8 v8.8.2 - go.opentelemetry.io/otel v0.20.0 - go.opentelemetry.io/otel/trace v0.20.0 + go.opentelemetry.io/otel v1.0.0-RC1 + go.opentelemetry.io/otel/trace v1.0.0-RC1 ) diff --git a/go.mod b/go.mod index 0b2ed13104..c792cdd44c 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.14 require ( github.com/cespare/xxhash/v2 v2.1.1 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f + github.com/google/go-cmp v0.5.6 // indirect github.com/onsi/ginkgo v1.15.0 github.com/onsi/gomega v1.10.5 - go.opentelemetry.io/otel/metric v0.20.0 ) diff --git a/go.sum b/go.sum index b8309364d9..76abf5b46c 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -18,8 +16,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -31,20 +29,7 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -95,5 +80,3 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/instruments.go b/internal/instruments.go deleted file mode 100644 index 49d6111e18..0000000000 --- a/internal/instruments.go +++ /dev/null @@ -1,33 +0,0 @@ -package internal - -import ( - "context" - - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/global" -) - -var ( - // WritesCounter is a count of write commands performed. - WritesCounter metric.Int64Counter - // NewConnectionsCounter is a count of new connections. - NewConnectionsCounter metric.Int64Counter -) - -func init() { - defer func() { - if r := recover(); r != nil { - Logger.Printf(context.Background(), "Error creating meter github.com/go-redis/redis for Instruments", r) - } - }() - - meter := metric.Must(global.Meter("github.com/go-redis/redis")) - - WritesCounter = meter.NewInt64Counter("redis.writes", - metric.WithDescription("the number of writes initiated"), - ) - - NewConnectionsCounter = meter.NewInt64Counter("redis.new_connections", - metric.WithDescription("the number of connections created"), - ) -} diff --git a/internal/pool/conn.go b/internal/pool/conn.go index 1ce29edd4b..5661659865 100644 --- a/internal/pool/conn.go +++ b/internal/pool/conn.go @@ -7,7 +7,6 @@ import ( "sync/atomic" "time" - "github.com/go-redis/redis/v8/internal" "github.com/go-redis/redis/v8/internal/proto" ) @@ -86,13 +85,7 @@ func (cn *Conn) WithWriter( return err } - if err := cn.bw.Flush(); err != nil { - return err - } - - internal.WritesCounter.Add(ctx, 1) - - return nil + return cn.bw.Flush() } func (cn *Conn) Close() error { diff --git a/internal/pool/pool.go b/internal/pool/pool.go index 4d247b3010..a8f0a6d4e2 100644 --- a/internal/pool/pool.go +++ b/internal/pool/pool.go @@ -188,7 +188,6 @@ func (p *ConnPool) dialConn(ctx context.Context, pooled bool) (*Conn, error) { return nil, err } - internal.NewConnectionsCounter.Add(ctx, 1) cn := NewConn(netConn) cn.pooled = pooled return cn, nil diff --git a/options.go b/options.go index 7cf1bc1bbf..8bbc27b82b 100644 --- a/options.go +++ b/options.go @@ -77,7 +77,7 @@ type Options struct { WriteTimeout time.Duration // Maximum number of socket connections. - // Default is 10 connections per every CPU as reported by runtime.NumCPU. + // Default is 10 connections per every available CPU as reported by runtime.GOMAXPROCS. PoolSize int // Minimum number of idle connections which is useful when establishing // new connection is slow. @@ -136,7 +136,7 @@ func (opt *Options) init() { } } if opt.PoolSize == 0 { - opt.PoolSize = 10 * runtime.NumCPU() + opt.PoolSize = 10 * runtime.GOMAXPROCS(0) } switch opt.ReadTimeout { case -1: diff --git a/redis.go b/redis.go index 2673e84ba3..051fa59455 100644 --- a/redis.go +++ b/redis.go @@ -128,7 +128,7 @@ func (hs hooks) processTxPipeline( return hs.processPipeline(ctx, cmds, fn) } -func (hs hooks) withContext(ctx context.Context, fn func() error) error { +func (hs hooks) withContext(_ context.Context, fn func() error) error { return fn() } From b8245b56f966ed9437d11d0afbe3792ae484f35d Mon Sep 17 00:00:00 2001 From: monkey Date: Sat, 24 Jul 2021 22:24:17 +0800 Subject: [PATCH 010/621] Remove redundant code. Signed-off-by: monkey --- commands_test.go | 66 ------------------------------------------------ 1 file changed, 66 deletions(-) diff --git a/commands_test.go b/commands_test.go index fb9bbfcd40..eb46a7904d 100644 --- a/commands_test.go +++ b/commands_test.go @@ -4127,45 +4127,6 @@ var _ = Describe("Commands", func() { })) }) - It("should ZUnion", func() { - err := client.ZAddArgs(ctx, "zset1", redis.ZAddArgs{ - Members: []redis.Z{ - {Score: 1, Member: "one"}, - {Score: 2, Member: "two"}, - }, - }).Err() - Expect(err).NotTo(HaveOccurred()) - - err = client.ZAddArgs(ctx, "zset2", redis.ZAddArgs{ - Members: []redis.Z{ - {Score: 1, Member: "one"}, - {Score: 2, Member: "two"}, - {Score: 3, Member: "three"}, - }, - }).Err() - Expect(err).NotTo(HaveOccurred()) - - union, err := client.ZUnion(ctx, redis.ZStore{ - Keys: []string{"zset1", "zset2"}, - Weights: []float64{2, 3}, - Aggregate: "sum", - }).Result() - Expect(err).NotTo(HaveOccurred()) - Expect(union).To(Equal([]string{"one", "three", "two"})) - - unionScores, err := client.ZUnionWithScores(ctx, redis.ZStore{ - Keys: []string{"zset1", "zset2"}, - Weights: []float64{2, 3}, - Aggregate: "sum", - }).Result() - Expect(err).NotTo(HaveOccurred()) - Expect(unionScores).To(Equal([]redis.Z{ - {Score: 5, Member: "one"}, - {Score: 9, Member: "three"}, - {Score: 10, Member: "two"}, - })) - }) - It("should ZUnionStore", func() { err := client.ZAdd(ctx, "zset1", redis.Z{Score: 1, Member: "one"}).Err() Expect(err).NotTo(HaveOccurred()) @@ -4392,33 +4353,6 @@ var _ = Describe("Commands", func() { Expect(n).To(Equal(int64(3))) }) - // TODO XTrimMaxLenApprox/XTrimMinIDApprox There is a bug in the limit parameter. - // TODO Don't test it for now. - // TODO link: https://github.com/redis/redis/issues/9046 - It("should XTrimMaxLen", func() { - n, err := client.XTrimMaxLen(ctx, "stream", 0).Result() - Expect(err).NotTo(HaveOccurred()) - Expect(n).To(Equal(int64(3))) - }) - - It("should XTrimMaxLenApprox", func() { - n, err := client.XTrimMaxLenApprox(ctx, "stream", 0, 0).Result() - Expect(err).NotTo(HaveOccurred()) - Expect(n).To(Equal(int64(3))) - }) - - It("should XTrimMinID", func() { - n, err := client.XTrimMinID(ctx, "stream", "4-0").Result() - Expect(err).NotTo(HaveOccurred()) - Expect(n).To(Equal(int64(3))) - }) - - It("should XTrimMinIDApprox", func() { - n, err := client.XTrimMinIDApprox(ctx, "stream", "4-0", 0).Result() - Expect(err).NotTo(HaveOccurred()) - Expect(n).To(Equal(int64(3))) - }) - It("should XAdd", func() { id, err := client.XAdd(ctx, &redis.XAddArgs{ Stream: "stream", From 38d1749d56f6ee41baf8222b3aa0aa0c6950f41d Mon Sep 17 00:00:00 2001 From: monkey92t Date: Mon, 2 Aug 2021 19:01:01 +0800 Subject: [PATCH 011/621] adjust the code (#1842) * Upgrade redis-server version (#1833) * Upgrade redis-server version Signed-off-by: monkey * XAutoClaim changed the return value Signed-off-by: monkey * add cmd: geosearch, geosearchstore (#1836) * add cmd: geosearch, geosearchstore Signed-off-by: monkey92t * GeoSearchQuery and GeoSearchLocationQuery changed to pointer passing Signed-off-by: monkey92t * adjust the code, and fix #1553, #1676 Signed-off-by: monkey92t --- Makefile | 2 +- cluster.go | 1 - cluster_test.go | 8 +- command.go | 177 +++++++++++++++++++++++++++++++++ command_test.go | 2 +- commands.go | 39 ++++++++ commands_test.go | 209 +++++++++++++++++++++++++++++++++++++-- export_test.go | 10 +- internal/proto/writer.go | 2 +- options.go | 5 +- pipeline.go | 40 ++------ pool_test.go | 1 - redis_test.go | 17 ---- ring.go | 2 +- ring_test.go | 1 - 15 files changed, 439 insertions(+), 77 deletions(-) diff --git a/Makefile b/Makefile index 5501164f96..b16709c8c5 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ bench: testdeps testdata/redis: mkdir -p $@ - wget -qO- https://download.redis.io/releases/redis-6.2.1.tar.gz | tar xvz --strip-components=1 -C $@ + wget -qO- https://download.redis.io/releases/redis-6.2.5.tar.gz | tar xvz --strip-components=1 -C $@ testdata/redis/src/redis-server: testdata/redis cd $< && make all diff --git a/cluster.go b/cluster.go index d85c043a19..bfc7d4e51b 100644 --- a/cluster.go +++ b/cluster.go @@ -795,7 +795,6 @@ func (c *ClusterClient) process(ctx context.Context, cmd Cmder) error { _ = pipe.Process(ctx, NewCmd(ctx, "asking")) _ = pipe.Process(ctx, cmd) _, lastErr = pipe.Exec(ctx) - _ = pipe.Close() ask = false } else { lastErr = node.Client.Process(ctx, cmd) diff --git a/cluster_test.go b/cluster_test.go index 4c4e4d310e..fa69262049 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -515,9 +515,7 @@ var _ = Describe("ClusterClient", func() { pipe = client.Pipeline().(*redis.Pipeline) }) - AfterEach(func() { - Expect(pipe.Close()).NotTo(HaveOccurred()) - }) + AfterEach(func() {}) assertPipeline() }) @@ -527,9 +525,7 @@ var _ = Describe("ClusterClient", func() { pipe = client.TxPipeline().(*redis.Pipeline) }) - AfterEach(func() { - Expect(pipe.Close()).NotTo(HaveOccurred()) - }) + AfterEach(func() {}) assertPipeline() }) diff --git a/command.go b/command.go index 1c53a66060..d1be104324 100644 --- a/command.go +++ b/command.go @@ -2564,6 +2564,183 @@ func (cmd *GeoLocationCmd) readReply(rd *proto.Reader) error { //------------------------------------------------------------------------------ +// GeoSearchQuery is used for GEOSearch/GEOSearchStore command query. +type GeoSearchQuery struct { + Member string + + // Latitude and Longitude when using FromLonLat option. + Longitude float64 + Latitude float64 + + // Distance and unit when using ByRadius option. + // Can use m, km, ft, or mi. Default is km. + Radius float64 + RadiusUnit string + + // Height, width and unit when using ByBox option. + // Can be m, km, ft, or mi. Default is km. + BoxWidth float64 + BoxHeight float64 + BoxUnit string + + // Can be ASC or DESC. Default is no sort order. + Sort string + Count int + CountAny bool +} + +type GeoSearchLocationQuery struct { + GeoSearchQuery + + WithCoord bool + WithDist bool + WithHash bool +} + +type GeoSearchStoreQuery struct { + GeoSearchQuery + + // When using the StoreDist option, the command stores the items in a + // sorted set populated with their distance from the center of the circle or box, + // as a floating-point number, in the same unit specified for that shape. + StoreDist bool +} + +func geoSearchLocationArgs(q *GeoSearchLocationQuery, args []interface{}) []interface{} { + args = geoSearchArgs(&q.GeoSearchQuery, args) + + if q.WithCoord { + args = append(args, "withcoord") + } + if q.WithDist { + args = append(args, "withdist") + } + if q.WithHash { + args = append(args, "withhash") + } + + return args +} + +func geoSearchArgs(q *GeoSearchQuery, args []interface{}) []interface{} { + if q.Member != "" { + args = append(args, "frommember", q.Member) + } else { + args = append(args, "fromlonlat", q.Longitude, q.Latitude) + } + + if q.Radius > 0 { + if q.RadiusUnit == "" { + q.RadiusUnit = "km" + } + args = append(args, "byradius", q.Radius, q.RadiusUnit) + } else { + if q.BoxUnit == "" { + q.BoxUnit = "km" + } + args = append(args, "bybox", q.BoxWidth, q.BoxHeight, q.BoxUnit) + } + + if q.Sort != "" { + args = append(args, q.Sort) + } + + if q.Count > 0 { + args = append(args, "count", q.Count) + if q.CountAny { + args = append(args, "any") + } + } + + return args +} + +type GeoSearchLocationCmd struct { + baseCmd + + opt *GeoSearchLocationQuery + val []GeoLocation +} + +var _ Cmder = (*GeoSearchLocationCmd)(nil) + +func NewGeoSearchLocationCmd( + ctx context.Context, opt *GeoSearchLocationQuery, args ...interface{}, +) *GeoSearchLocationCmd { + return &GeoSearchLocationCmd{ + baseCmd: baseCmd{ + ctx: ctx, + args: args, + }, + opt: opt, + } +} + +func (cmd *GeoSearchLocationCmd) Val() []GeoLocation { + return cmd.val +} + +func (cmd *GeoSearchLocationCmd) Result() ([]GeoLocation, error) { + return cmd.val, cmd.err +} + +func (cmd *GeoSearchLocationCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *GeoSearchLocationCmd) readReply(rd *proto.Reader) error { + n, err := rd.ReadArrayLen() + if err != nil { + return err + } + + cmd.val = make([]GeoLocation, n) + for i := 0; i < n; i++ { + _, err = rd.ReadArrayLen() + if err != nil { + return err + } + + var loc GeoLocation + + loc.Name, err = rd.ReadString() + if err != nil { + return err + } + if cmd.opt.WithDist { + loc.Dist, err = rd.ReadFloat() + if err != nil { + return err + } + } + if cmd.opt.WithHash { + loc.GeoHash, err = rd.ReadInt() + if err != nil { + return err + } + } + if cmd.opt.WithCoord { + if err = rd.ReadFixedArrayLen(2); err != nil { + return err + } + loc.Longitude, err = rd.ReadFloat() + if err != nil { + return err + } + loc.Latitude, err = rd.ReadFloat() + if err != nil { + return err + } + } + + cmd.val[i] = loc + } + + return nil +} + +//------------------------------------------------------------------------------ + type GeoPos struct { Longitude, Latitude float64 } diff --git a/command_test.go b/command_test.go index d110d0c33a..9877df4273 100644 --- a/command_test.go +++ b/command_test.go @@ -4,7 +4,7 @@ import ( "errors" "time" - redis "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v8" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" diff --git a/commands.go b/commands.go index 346e38e9f1..b63aa0136d 100644 --- a/commands.go +++ b/commands.go @@ -244,6 +244,7 @@ type Cmdable interface { XTrimMinIDApprox(ctx context.Context, key string, minID string, limit int64) *IntCmd XInfoGroups(ctx context.Context, key string) *XInfoGroupsCmd XInfoStream(ctx context.Context, key string) *XInfoStreamCmd + XInfoStreamFull(ctx context.Context, key string, count int) *XInfoStreamFullCmd XInfoConsumers(ctx context.Context, key string, group string) *XInfoConsumersCmd BZPopMax(ctx context.Context, timeout time.Duration, keys ...string) *ZWithKeyCmd @@ -304,6 +305,8 @@ type Cmdable interface { ClientList(ctx context.Context) *StringCmd ClientPause(ctx context.Context, dur time.Duration) *BoolCmd ClientID(ctx context.Context) *IntCmd + ClientUnblock(ctx context.Context, id int64) *IntCmd + ClientUnblockWithError(ctx context.Context, id int64) *IntCmd ConfigGet(ctx context.Context, parameter string) *MapStringStringCmd ConfigResetStat(ctx context.Context) *StatusCmd ConfigSet(ctx context.Context, parameter, value string) *StatusCmd @@ -320,6 +323,7 @@ type Cmdable interface { ShutdownSave(ctx context.Context) *StatusCmd ShutdownNoSave(ctx context.Context) *StatusCmd SlaveOf(ctx context.Context, host, port string) *StatusCmd + SlowLogGet(ctx context.Context, num int64) *SlowLogCmd Time(ctx context.Context) *TimeCmd DebugObject(ctx context.Context, key string) *StringCmd ReadOnly(ctx context.Context) *StatusCmd @@ -364,6 +368,9 @@ type Cmdable interface { GeoRadiusStore(ctx context.Context, key string, longitude, latitude float64, query *GeoRadiusQuery) *IntCmd GeoRadiusByMember(ctx context.Context, key, member string, query *GeoRadiusQuery) *GeoLocationCmd GeoRadiusByMemberStore(ctx context.Context, key, member string, query *GeoRadiusQuery) *IntCmd + GeoSearch(ctx context.Context, key string, q *GeoSearchQuery) *StringSliceCmd + GeoSearchLocation(ctx context.Context, key string, q *GeoSearchLocationQuery) *GeoSearchLocationCmd + GeoSearchStore(ctx context.Context, key, store string, q *GeoSearchStoreQuery) *IntCmd GeoDist(ctx context.Context, key string, member1, member2, unit string) *FloatCmd GeoHash(ctx context.Context, key string, members ...string) *StringSliceCmd } @@ -3240,6 +3247,38 @@ func (c cmdable) GeoRadiusByMemberStore( return cmd } +func (c cmdable) GeoSearch(ctx context.Context, key string, q *GeoSearchQuery) *StringSliceCmd { + args := make([]interface{}, 0, 13) + args = append(args, "geosearch", key) + args = geoSearchArgs(q, args) + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) GeoSearchLocation( + ctx context.Context, key string, q *GeoSearchLocationQuery, +) *GeoSearchLocationCmd { + args := make([]interface{}, 0, 16) + args = append(args, "geosearch", key) + args = geoSearchLocationArgs(q, args) + cmd := NewGeoSearchLocationCmd(ctx, q, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) GeoSearchStore(ctx context.Context, key, store string, q *GeoSearchStoreQuery) *IntCmd { + args := make([]interface{}, 0, 15) + args = append(args, "geosearchstore", store, key) + args = geoSearchArgs(&q.GeoSearchQuery, args) + if q.StoreDist { + args = append(args, "storedist") + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) GeoDist( ctx context.Context, key string, member1, member2, unit string, ) *FloatCmd { diff --git a/commands_test.go b/commands_test.go index eb46a7904d..06d6e40184 100644 --- a/commands_test.go +++ b/commands_test.go @@ -4657,7 +4657,7 @@ var _ = Describe("Commands", func() { } msgs, start, err := client.XAutoClaim(ctx, xca).Result() Expect(err).NotTo(HaveOccurred()) - Expect(start).To(Equal("2-0")) + Expect(start).To(Equal("3-0")) Expect(msgs).To(Equal([]redis.XMessage{{ ID: "1-0", Values: map[string]interface{}{"uno": "un"}, @@ -4669,19 +4669,16 @@ var _ = Describe("Commands", func() { xca.Start = start msgs, start, err = client.XAutoClaim(ctx, xca).Result() Expect(err).NotTo(HaveOccurred()) - Expect(start).To(Equal("3-0")) + Expect(start).To(Equal("0-0")) Expect(msgs).To(Equal([]redis.XMessage{{ - ID: "2-0", - Values: map[string]interface{}{"dos": "deux"}, - }, { ID: "3-0", Values: map[string]interface{}{"tres": "troix"}, }})) ids, start, err := client.XAutoClaimJustID(ctx, xca).Result() Expect(err).NotTo(HaveOccurred()) - Expect(start).To(Equal("3-0")) - Expect(ids).To(Equal([]string{"2-0", "3-0"})) + Expect(start).To(Equal("0-0")) + Expect(ids).To(Equal([]string{"3-0"})) }) It("should XClaim", func() { @@ -5167,6 +5164,204 @@ var _ = Describe("Commands", func() { nil, })) }) + + It("should geo search", func() { + q := &redis.GeoSearchQuery{ + Member: "Catania", + BoxWidth: 400, + BoxHeight: 100, + BoxUnit: "km", + Sort: "asc", + } + val, err := client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania"})) + + q.BoxHeight = 400 + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania", "Palermo"})) + + q.Count = 1 + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania"})) + + q.CountAny = true + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Palermo"})) + + q = &redis.GeoSearchQuery{ + Member: "Catania", + Radius: 100, + RadiusUnit: "km", + Sort: "asc", + } + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania"})) + + q.Radius = 400 + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania", "Palermo"})) + + q.Count = 1 + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania"})) + + q.CountAny = true + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Palermo"})) + + q = &redis.GeoSearchQuery{ + Longitude: 15, + Latitude: 37, + BoxWidth: 200, + BoxHeight: 200, + BoxUnit: "km", + Sort: "asc", + } + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania"})) + + q.BoxWidth, q.BoxHeight = 400, 400 + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania", "Palermo"})) + + q.Count = 1 + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania"})) + + q.CountAny = true + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Palermo"})) + + q = &redis.GeoSearchQuery{ + Longitude: 15, + Latitude: 37, + Radius: 100, + RadiusUnit: "km", + Sort: "asc", + } + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania"})) + + q.Radius = 200 + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania", "Palermo"})) + + q.Count = 1 + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Catania"})) + + q.CountAny = true + val, err = client.GeoSearch(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]string{"Palermo"})) + }) + + It("should geo search with options", func() { + q := &redis.GeoSearchLocationQuery{ + GeoSearchQuery: redis.GeoSearchQuery{ + Longitude: 15, + Latitude: 37, + Radius: 200, + RadiusUnit: "km", + Sort: "asc", + }, + WithHash: true, + WithDist: true, + WithCoord: true, + } + val, err := client.GeoSearchLocation(ctx, "Sicily", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal([]redis.GeoLocation{ + { + Name: "Catania", + Longitude: 15.08726745843887329, + Latitude: 37.50266842333162032, + Dist: 56.4413, + GeoHash: 3479447370796909, + }, + { + Name: "Palermo", + Longitude: 13.36138933897018433, + Latitude: 38.11555639549629859, + Dist: 190.4424, + GeoHash: 3479099956230698, + }, + })) + }) + + It("should geo search store", func() { + q := &redis.GeoSearchStoreQuery{ + GeoSearchQuery: redis.GeoSearchQuery{ + Longitude: 15, + Latitude: 37, + Radius: 200, + RadiusUnit: "km", + Sort: "asc", + }, + StoreDist: false, + } + + val, err := client.GeoSearchStore(ctx, "Sicily", "key1", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal(int64(2))) + + q.StoreDist = true + val, err = client.GeoSearchStore(ctx, "Sicily", "key2", q).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal(int64(2))) + + loc, err := client.GeoSearchLocation(ctx, "key1", &redis.GeoSearchLocationQuery{ + GeoSearchQuery: q.GeoSearchQuery, + WithCoord: true, + WithDist: true, + WithHash: true, + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(loc).To(Equal([]redis.GeoLocation{ + { + Name: "Catania", + Longitude: 15.08726745843887329, + Latitude: 37.50266842333162032, + Dist: 56.4413, + GeoHash: 3479447370796909, + }, + { + Name: "Palermo", + Longitude: 13.36138933897018433, + Latitude: 38.11555639549629859, + Dist: 190.4424, + GeoHash: 3479099956230698, + }, + })) + + v, err := client.ZRangeWithScores(ctx, "key2", 0, -1).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(v).To(Equal([]redis.Z{ + { + Score: 56.441257870158204, + Member: "Catania", + }, + { + Score: 190.44242984775784, + Member: "Palermo", + }, + })) + }) }) Describe("marshaling/unmarshaling", func() { diff --git a/export_test.go b/export_test.go index 49c4b94cee..e243a19274 100644 --- a/export_test.go +++ b/export_test.go @@ -60,21 +60,21 @@ func (c *ClusterClient) SwapNodes(ctx context.Context, key string) error { return nil } -func (state *clusterState) IsConsistent(ctx context.Context) bool { - if len(state.Masters) < 3 { +func (c *clusterState) IsConsistent(ctx context.Context) bool { + if len(c.Masters) < 3 { return false } - for _, master := range state.Masters { + for _, master := range c.Masters { s := master.Client.Info(ctx, "replication").Val() if !strings.Contains(s, "role:master") { return false } } - if len(state.Slaves) < 3 { + if len(c.Slaves) < 3 { return false } - for _, slave := range state.Slaves { + for _, slave := range c.Slaves { s := slave.Client.Info(ctx, "replication").Val() if !strings.Contains(s, "role:slave") { return false diff --git a/internal/proto/writer.go b/internal/proto/writer.go index 72b30441b7..f2dc5c936a 100644 --- a/internal/proto/writer.go +++ b/internal/proto/writer.go @@ -13,7 +13,7 @@ import ( type writer interface { io.Writer io.ByteWriter - // io.StringWriter + // WriteString implement io.StringWriter. WriteString(s string) (n int, err error) } diff --git a/options.go b/options.go index 5d39bf0492..e1e85a663e 100644 --- a/options.go +++ b/options.go @@ -247,7 +247,10 @@ func setupTCPConn(u *url.URL) (*Options, error) { } if u.Scheme == "rediss" { - o.TLSConfig = &tls.Config{ServerName: h} + o.TLSConfig = &tls.Config{ + ServerName: h, + MinVersion: tls.VersionTLS12, + } } return o, nil diff --git a/pipeline.go b/pipeline.go index c6ec340998..aa2fc8f03e 100644 --- a/pipeline.go +++ b/pipeline.go @@ -3,8 +3,6 @@ package redis import ( "context" "sync" - - "github.com/go-redis/redis/v8/internal/pool" ) type pipelineExecer func(context.Context, []Cmder) error @@ -26,8 +24,7 @@ type Pipeliner interface { StatefulCmdable Do(ctx context.Context, args ...interface{}) *Cmd Process(ctx context.Context, cmd Cmder) error - Close() error - Discard() error + Discard() Exec(ctx context.Context) ([]Cmder, error) } @@ -43,9 +40,8 @@ type Pipeline struct { ctx context.Context exec pipelineExecer - mu sync.Mutex - cmds []Cmder - closed bool + mu sync.Mutex + cmds []Cmder } func (c *Pipeline) init() { @@ -67,29 +63,11 @@ func (c *Pipeline) Process(ctx context.Context, cmd Cmder) error { return nil } -// Close closes the pipeline, releasing any open resources. -func (c *Pipeline) Close() error { - c.mu.Lock() - _ = c.discard() - c.closed = true - c.mu.Unlock() - return nil -} - // Discard resets the pipeline and discards queued commands. -func (c *Pipeline) Discard() error { +func (c *Pipeline) Discard() { c.mu.Lock() - err := c.discard() - c.mu.Unlock() - return err -} - -func (c *Pipeline) discard() error { - if c.closed { - return pool.ErrClosed - } c.cmds = c.cmds[:0] - return nil + c.mu.Unlock() } // Exec executes all previously queued commands using one @@ -101,10 +79,6 @@ func (c *Pipeline) Exec(ctx context.Context) ([]Cmder, error) { c.mu.Lock() defer c.mu.Unlock() - if c.closed { - return nil, pool.ErrClosed - } - if len(c.cmds) == 0 { return nil, nil } @@ -119,9 +93,7 @@ func (c *Pipeline) Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]C if err := fn(c); err != nil { return nil, err } - cmds, err := c.Exec(ctx) - _ = c.Close() - return cmds, err + return c.Exec(ctx) } func (c *Pipeline) Pipeline() Pipeliner { diff --git a/pool_test.go b/pool_test.go index 81318199e3..5e83549c5c 100644 --- a/pool_test.go +++ b/pool_test.go @@ -72,7 +72,6 @@ var _ = Describe("pool", func() { Expect(cmds).To(HaveLen(1)) Expect(ping.Err()).NotTo(HaveOccurred()) Expect(ping.Val()).To(Equal("PONG")) - Expect(pipe.Close()).NotTo(HaveOccurred()) }) pool := client.Pool() diff --git a/redis_test.go b/redis_test.go index 9f189052dc..c2d2dc023b 100644 --- a/redis_test.go +++ b/redis_test.go @@ -136,17 +136,6 @@ var _ = Describe("Client", func() { Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred()) }) - It("should close pipeline without closing the client", func() { - pipeline := client.Pipeline() - Expect(pipeline.Close()).NotTo(HaveOccurred()) - - pipeline.Ping(ctx) - _, err := pipeline.Exec(ctx) - Expect(err).To(MatchError("redis: client is closed")) - - Expect(client.Ping(ctx).Err()).NotTo(HaveOccurred()) - }) - It("should close pubsub when client is closed", func() { pubsub := client.Subscribe(ctx) Expect(client.Close()).NotTo(HaveOccurred()) @@ -157,12 +146,6 @@ var _ = Describe("Client", func() { Expect(pubsub.Close()).NotTo(HaveOccurred()) }) - It("should close pipeline when client is closed", func() { - pipeline := client.Pipeline() - Expect(client.Close()).NotTo(HaveOccurred()) - Expect(pipeline.Close()).NotTo(HaveOccurred()) - }) - It("should select DB", func() { db2 := redis.NewClient(&redis.Options{ Addr: redisAddr, diff --git a/ring.go b/ring.go index 5e35b6bb6a..7446d32c24 100644 --- a/ring.go +++ b/ring.go @@ -308,7 +308,7 @@ func (c *ringShards) Random() (*ringShard, error) { return c.GetByKey(strconv.Itoa(rand.Int())) } -// heartbeat monitors state of each shard in the ring. +// Heartbeat monitors state of each shard in the ring. func (c *ringShards) Heartbeat(frequency time.Duration) { ticker := time.NewTicker(frequency) defer ticker.Stop() diff --git a/ring_test.go b/ring_test.go index 4a434a5b52..432a1c0704 100644 --- a/ring_test.go +++ b/ring_test.go @@ -123,7 +123,6 @@ var _ = Describe("Redis Ring", func() { cmds, err := pipe.Exec(ctx) Expect(err).NotTo(HaveOccurred()) Expect(cmds).To(HaveLen(100)) - Expect(pipe.Close()).NotTo(HaveOccurred()) for _, cmd := range cmds { Expect(cmd.Err()).NotTo(HaveOccurred()) From 4261a2cb2a9bf1a2a1c0f8d2ac655c78db10f709 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Mon, 2 Aug 2021 14:03:38 +0300 Subject: [PATCH 012/621] Update changelog for v9 (#1843) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63aabd3d97..c6c62602ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ > :heart: > [**Uptrace.dev** - All-in-one tool to optimize performance and monitor errors & logs](https://uptrace.dev) +## v9 UNRELEASED + +- Added support for [RESP3](https://github.com/antirez/RESP3/blob/master/spec.md) protocol. +- Removed `Pipeline.Close` since there is no real need to explicitly manage pipeline resources. + `Pipeline.Discard` is still available if you want to reset commands for some reason. +- Replaced `*redis.Z` with `redis.Z` since it is small enough to be passed as value. + ## v8.11 - Remove OpenTelemetry metrics. From bf334e773819574a898717f5a709e15cecaa43ff Mon Sep 17 00:00:00 2001 From: wjdqhry Date: Fri, 17 Dec 2021 11:54:43 +0900 Subject: [PATCH 013/621] feat: enable struct on HSet --- commands.go | 30 ++++++++++++++++++++++++++++++ example_test.go | 14 ++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/commands.go b/commands.go index dfe8d0bb55..5ee66fab85 100644 --- a/commands.go +++ b/commands.go @@ -4,6 +4,7 @@ import ( "context" "errors" "io" + "reflect" "time" "github.com/go-redis/redis/v8/internal" @@ -78,6 +79,29 @@ func appendArg(dst []interface{}, arg interface{}) []interface{} { } } +func structToMap(items interface{}) map[string]interface{} { + res := map[string]interface{}{} + if items == nil { + return res + } + v := reflect.TypeOf(items) + reflectValue := reflect.Indirect(reflect.ValueOf(items)) + + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + for i := 0; i < v.NumField(); i++ { + tag := v.Field(i).Tag.Get("json") + + if tag != "" && v.Field(i).Type.Kind() != reflect.Struct { + field := reflectValue.Field(i).Interface() + res[tag] = field + } + } + + return res +} + type Cmdable interface { Pipeline() Pipeliner Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error) @@ -1261,9 +1285,15 @@ func (c cmdable) HMGet(ctx context.Context, key string, fields ...string) *Slice // - HSet("myhash", "key1", "value1", "key2", "value2") // - HSet("myhash", []string{"key1", "value1", "key2", "value2"}) // - HSet("myhash", map[string]interface{}{"key1": "value1", "key2": "value2"}) +// - HSet("myhash", struct{Key1: "value1"; Key2: "value2"}) // // Note that it requires Redis v4 for multiple field/value pairs support. func (c cmdable) HSet(ctx context.Context, key string, values ...interface{}) *IntCmd { + if len(values) == 1 { + if reflect.ValueOf(values[0]).Kind() == reflect.Struct { + values = []interface{}{structToMap(values[0])} + } + } args := make([]interface{}, 2, 2+len(values)) args[0] = "hset" args[1] = key diff --git a/example_test.go b/example_test.go index f015809633..46bed6f075 100644 --- a/example_test.go +++ b/example_test.go @@ -197,6 +197,20 @@ func ExampleClient_SetEX() { } } +func ExampleClient_HSet() { + type Items struct { + Key1 string `json:"key1"` + Key2 string `json:"key2"` + } + items := Items{"field1", "field2"} + // Last argument is expiration. Zero means the key has no + // expiration time. + err := rdb.HSet(ctx, "key", items).Err() + if err != nil { + panic(err) + } +} + func ExampleClient_Incr() { result, err := rdb.Incr(ctx, "counter").Result() if err != nil { From 4ce90461a5572395f0bffcf1e0eb5f17ae31ce11 Mon Sep 17 00:00:00 2001 From: wjdqhry Date: Wed, 22 Dec 2021 14:26:40 +0900 Subject: [PATCH 014/621] fix: remove comment --- example_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example_test.go b/example_test.go index 46bed6f075..e696fdfe79 100644 --- a/example_test.go +++ b/example_test.go @@ -203,8 +203,7 @@ func ExampleClient_HSet() { Key2 string `json:"key2"` } items := Items{"field1", "field2"} - // Last argument is expiration. Zero means the key has no - // expiration time. + err := rdb.HSet(ctx, "key", items).Err() if err != nil { panic(err) From 52276c393d8983d8475438f152d4744fb0569d94 Mon Sep 17 00:00:00 2001 From: nick comer Date: Fri, 14 Jan 2022 16:01:09 -0500 Subject: [PATCH 015/621] feat: extract dialer to `DefaultDialer` to allow wrapping Allowing the default dialing function to be wrapped allows for library users to let the library continue to own the logic for dialing and let users wrap the function for more observability. My use case is to override `Options.Dialer` and add Jaeger tracing to gain insight into the cost of new connections on a latency sensitive API. ```go defDialer := redis.DefaultDialer(opts) opts.Dialer = func(ctx context.Context, network, addr string) (net.Conn, error) { span, ctx := opentracing.StartSpanFromContext(ctx, "cache-repo-redis: new redis connection") defer span.Finish() return defDialer(ctx, network, addr) } ``` Without this, I end up needing to copy-paste the code from the internal code, which is less-than-ideal since I don't want to own the maintenance of this logic. --- options.go | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/options.go b/options.go index a4abe32c3a..cbdb54ec4e 100644 --- a/options.go +++ b/options.go @@ -129,16 +129,7 @@ func (opt *Options) init() { opt.DialTimeout = 5 * time.Second } if opt.Dialer == nil { - opt.Dialer = func(ctx context.Context, network, addr string) (net.Conn, error) { - netDialer := &net.Dialer{ - Timeout: opt.DialTimeout, - KeepAlive: 5 * time.Minute, - } - if opt.TLSConfig == nil { - return netDialer.DialContext(ctx, network, addr) - } - return tls.DialWithDialer(netDialer, network, addr, opt.TLSConfig) - } + opt.Dialer = DefaultDialer(opt) } if opt.PoolSize == 0 { opt.PoolSize = 10 * runtime.GOMAXPROCS(0) @@ -189,6 +180,21 @@ func (opt *Options) clone() *Options { return &clone } +// DefaultDialer returns a function that will be used as the default dialer +// when none is specified in Options.Dialer. +func DefaultDialer(opt *Options) func(context.Context, string, string) (net.Conn, error) { + return func(ctx context.Context, network, addr string) (net.Conn, error) { + netDialer := &net.Dialer{ + Timeout: opt.DialTimeout, + KeepAlive: 5 * time.Minute, + } + if opt.TLSConfig == nil { + return netDialer.DialContext(ctx, network, addr) + } + return tls.DialWithDialer(netDialer, network, addr, opt.TLSConfig) + } +} + // ParseURL parses an URL into Options that can be used to connect to Redis. // Scheme is required. // There are two connection types: by tcp socket and by unix socket. From 335d946cd67daeb38683eb426dcb7b42783e44ef Mon Sep 17 00:00:00 2001 From: Monkey Date: Sat, 19 Mar 2022 12:40:31 +0800 Subject: [PATCH 016/621] chore: sync master (#2051) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Upgrade redis-server version (#1833) * Upgrade redis-server version Signed-off-by: monkey * XAutoClaim changed the return value Signed-off-by: monkey * add cmd: geosearch, geosearchstore (#1836) * add cmd: geosearch, geosearchstore Signed-off-by: monkey92t * GeoSearchQuery and GeoSearchLocationQuery changed to pointer passing Signed-off-by: monkey92t * Added missing method XInfoStreamFull to Cmdable interface * Run go mod tidy in redisotel Signed-off-by: Bogdan Drutu * Revert "ConnPool check fd for bad conns (#1824)" (#1849) This reverts commit 346bfafddd36dd52d51b064033048de5552ee91e. * Automate release process (#1852) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 (#1832) * Bump github.com/onsi/gomega from 1.10.5 to 1.14.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.10.5 to 1.14.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.10.5...v1.14.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Upgrade gomega to v1.15.0 Signed-off-by: monkey92t Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: monkey92t * Add version.go * Fix otel example * Fix package name in release script * More fixes for otel example * And more * Fix release.sh * Release v8.11.3 (release.sh) * Create an annotated tag to give release.yml chance to run * Tweak tag.sh * Add Cmd.Slice helper to cast to []interface{} (#1859) * after the connection pool is closed, no new connections should be added (#1863) * after the connection pool is closed, no new connections should be added Signed-off-by: monkey92t * remove runGoroutine Signed-off-by: monkey92t * pool.popIdle add p.closed check Signed-off-by: monkey92t * upgrade golangci-lint v1.42.0 Signed-off-by: monkey92t * Bump github.com/onsi/gomega from 1.15.0 to 1.16.0 (#1865) Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.15.0 to 1.16.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.15.0...v1.16.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add go 1.17 to the build matrix * Remove go 1.15 from build matrix * Add scan struct example (#1870) * Replace release job * Bump github.com/cespare/xxhash/v2 from 2.1.1 to 2.1.2 (#1872) Bumps [github.com/cespare/xxhash/v2](https://github.com/cespare/xxhash) from 2.1.1 to 2.1.2. - [Release notes](https://github.com/cespare/xxhash/releases) - [Commits](https://github.com/cespare/xxhash/compare/v2.1.1...v2.1.2) --- updated-dependencies: - dependency-name: github.com/cespare/xxhash/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix tag script to push tag by tag * Fix releasing.md * Fix/pubsub ping mutex (#1878) * Fix PubSub.Ping to hold the lock * Fix PubSub.Ping to hold the lock * add write cmd data-race test Signed-off-by: monkey92t Co-authored-by: monkey92t * chore: cleanup OpenTelemetry example * chore: gofmt all code * Refactor TestParseURL This is in preparation for supporting query parameters in ParseURL: - use an expected *Options instance to execute assertions on - extract assertions into helper function - enable parallel testing - condense test table * Add query parameter parsing to ParseURL() Before this change, ParseURL would only accept a very restricted set of URLs (it returned an error, if it encountered any parameter). This commit introduces the ability to process URLs like redis://localhost/1?dial_timeout=10s and similar. Go programs which were providing a configuration tunable (e.g. CLI flag, config entry or environment variable) to configure the Redis connection now don't need to perform this task themselves. * chore: add links to readme * chore: fix discussions link * empty hooks.withContext removed * chore: gofmt * chore: use conventional commits and auto-generate changelog * feat: add acl auth support for sentinels * chore: swap to acl auth at the test-level * Add support for BLMove command * chore: update dependencies * chore: update link * feat: add SetVal method for each command * feat: add Cmd.{String,Int,Float,Bool}Slice helpers and an example * chore: tweak GH actions to run all jobs * chore: add Lua scripting example * Fix Redis Cluster issue during roll outs of new nodes with same addr (#1914) * fix: recycle connections in some Redis Cluster scenarios This issue was surfaced in a Cloud Provider solution that used for rolling out new nodes using the same address (hostname) of the nodes that will be replaced in a Redis Cluster, while the former ones once depromoted as Slaves would continue in service during some mintues for redirecting traffic. The solution basically identifies when the connection could be stale since a MOVED response will be returned using the same address (hostname) that is being used by the connection. At that moment we consider the connection as no longer usable forcing to recycle the connection. * chore: lazy reload when moved or ask * chore: use conv commit message * chore: release v8.11.4 (release.sh) * fix: add whitespace for avoid unlikely colisions * fix: format * chore: fix links * chore: use ctx parameter in cmdInfo * Bump github.com/onsi/ginkgo from 1.16.4 to 1.16.5 (#1925) Bumps [github.com/onsi/ginkgo](https://github.com/onsi/ginkgo) from 1.16.4 to 1.16.5. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v1.16.4...v1.16.5) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add support for time.Duration write and scan * test: add test case for setting and scanning durations * chore: fix linter * fix(extra/redisotel): set span.kind attribute to client According to the opentelemetry specification this should always be set to client for database client libraries. I've also removed the SetAttributes call and instead set the attributes during creation of the span. This is what the library SHOULD be doing according to the opentelemetry api specification. * chore: update otel example * fix: update some argument counts in pre-allocs In some cases number of pre-allocated places in argument array is missing 1 or 2 elements, which results in re-allocation of twice as large array * chore: add example how to delete keys without a ttl * chore: don't enable all lints * chore(deps): bump github.com/onsi/gomega from 1.16.0 to 1.17.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * feat: Add redis v7's NX, XX, GT, LT expire variants * chore: add missing readme * chore: tweak feature links * chore: remove Discord * fix: set timeout for WAIT command. Fixes #1963 * build: update `go` directive in `go.mod` to 1.17 This commit enables support for module graph pruning and lazy module loading for projects that are at Go 1.17 or higher. Reference: https://go.dev/ref/mod#go-mod-file-go Reference: https://go.dev/ref/mod#graph-pruning Reference: https://go.dev/ref/mod#lazy-loading Signed-off-by: Eng Zer Jun * chore: update link * chore: export cmder.SetFirstKeyPos to support build module commands * feat(redisotel): ability to override TracerProvider (#1998) * fix: add missing Expire methods to Cmdable This is a followup to https://github.com/go-redis/redis/pull/1928 * chore(deps): bump github.com/onsi/gomega from 1.17.0 to 1.18.1 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.17.0 to 1.18.1. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.17.0...v1.18.1) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update README.md (#2011) chore: add fmt library in example code * chore: instrumentation name and version (#2012) * fix: invalid type assert in stringArg * chore: cleanup * fix: example/otel compile error (#2028) * fix: rename Golang to Go (#2030) https://go.dev/doc/faq#go_or_golang * feat: add support for passing extra attributes added to spans * feat: set net.peer.name and net.peer.port in otel example * chore: tweak Uptrace copy * feat: add support for COPY command (#2016) * feat: add support for acl sentinel auth in universal client * chore(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * chore: add hll example * chore: tweak release script * chore: release v8.11.5 (release.sh) * chore: add discord back Co-authored-by: Eugene Ponizovsky Co-authored-by: Bogdan Drutu Co-authored-by: Vladimir Mihailenco Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kishan B Co-authored-by: Dominik Menke Co-authored-by: Gökhan Özeloğlu Co-authored-by: Justin Sievenpiper Co-authored-by: Алексей Романовский Co-authored-by: Stavros Panakakakis Co-authored-by: Pau Freixes Co-authored-by: Ethan Hur Co-authored-by: Jackie <18378976+Pyrodash@users.noreply.github.com> Co-authored-by: Kristinn Björgvin Árdal Co-authored-by: ffenix113 Co-authored-by: Bastien Penavayre Co-authored-by: James3 Li(李麒傑) Co-authored-by: Eng Zer Jun Co-authored-by: gzjiangtao2014 Co-authored-by: Nelz Co-authored-by: Daniel Richter Co-authored-by: Seyed Ali Ghaffari Co-authored-by: lintanghui Co-authored-by: hidu Co-authored-by: Jonas Lergell Co-authored-by: Alex Kahn --- .github/FUNDING.yml | 2 +- .github/ISSUE_TEMPLATE/config.yml | 3 - .github/workflows/build.yml | 5 +- .github/workflows/commitlint.yml | 11 + .github/workflows/golangci-lint.yml | 2 +- .github/workflows/release.yml | 17 + .golangci.yml | 22 -- .prettierrc => .prettierrc.yml | 0 CHANGELOG.md | 40 ++- Makefile | 19 +- README.md | 38 +-- RELEASING.md | 15 + bench_test.go | 66 ++++ cluster.go | 20 +- cluster_test.go | 6 +- command.go | 307 +++++++++++++++++- command_test.go | 2 +- commands.go | 92 +++++- commands_test.go | 58 +++- error.go | 26 +- example/del-keys-without-ttl/README.md | 11 + example/del-keys-without-ttl/go.mod | 7 + .../del-keys-without-ttl}/go.sum | 99 +++--- example/del-keys-without-ttl/main.go | 142 ++++++++ example/hll/README.md | 9 + example/hll/go.mod | 7 + example/hll/go.sum | 110 +++++++ example/hll/main.go | 30 ++ example/lua-scripting/README.md | 8 + example/lua-scripting/go.mod | 7 + example/lua-scripting/go.sum | 110 +++++++ example/lua-scripting/main.go | 66 ++++ example/otel/README.md | 39 ++- example/otel/docker-compose.yml | 3 +- example/otel/example-client.go | 85 ----- example/otel/go.mod | 23 +- example/otel/go.sum | 253 +++++++++++++-- example/otel/main.go | 72 ++++ example/redis-bloom/README.md | 12 + example/redis-bloom/go.mod | 7 + example/redis-bloom/go.sum | 110 +++++++ example/redis-bloom/main.go | 155 +++++++++ example/scan-struct/README.md | 11 + example/scan-struct/go.mod | 10 + example/scan-struct/go.sum | 111 +++++++ example/scan-struct/main.go | 51 +++ example_test.go | 4 +- extra/rediscensus/go.mod | 9 +- extra/rediscensus/go.sum | 76 +++-- extra/rediscensus/rediscensus.go | 3 +- extra/rediscmd/go.mod | 8 +- extra/rediscmd/go.sum | 71 ++-- extra/rediscmd/safe.go | 1 + extra/rediscmd/unsafe.go | 1 + extra/redisotel/example/Makefile | 8 - extra/redisotel/example/README.md | 13 - extra/redisotel/example/docker-compose.yml | 8 - extra/redisotel/example/go.mod | 12 - extra/redisotel/example/main.go | 39 --- extra/redisotel/go.mod | 9 +- extra/redisotel/go.sum | 86 +++-- extra/redisotel/redisotel.go | 104 ++++-- extra/redisotel/redisotel_test.go | 68 ++++ fuzz/fuzz.go | 4 +- go.mod | 19 +- go.sum | 60 +++- internal/hashtag/hashtag_test.go | 4 +- internal/hscan/hscan_test.go | 2 +- internal/hscan/structmap.go | 6 +- internal/pool/conncheck.go | 45 --- internal/pool/conncheck_dummy.go | 9 - internal/pool/conncheck_test.go | 46 --- internal/pool/export_test.go | 4 +- internal/pool/main_test.go | 87 +---- internal/pool/pool.go | 40 ++- internal/pool/pool_test.go | 41 ++- internal/proto/reader.go | 2 +- internal/proto/scan.go | 8 + internal/proto/scan_test.go | 3 +- internal/proto/writer.go | 2 + internal/proto/writer_test.go | 6 +- internal/safe.go | 1 + internal/unsafe.go | 1 + internal/util/safe.go | 1 + internal/util/unsafe.go | 1 + iterator_test.go | 4 +- main_test.go | 8 +- options.go | 151 ++++++++- options_test.go | 295 +++++++++-------- package.json | 8 + pipeline.go | 10 + pipeline_test.go | 4 +- pool_test.go | 7 +- pubsub.go | 12 +- pubsub_test.go | 4 +- race_test.go | 16 +- redis.go | 31 +- redis_test.go | 16 +- ring.go | 5 +- ring_test.go | 8 +- scripts/bump_deps.sh | 9 + scripts/release.sh | 69 ++++ scripts/tag.sh | 42 +++ sentinel.go | 9 +- sentinel_test.go | 79 ++++- tx.go | 3 +- tx_test.go | 13 +- universal.go | 2 + version.go | 6 + 109 files changed, 3080 insertions(+), 942 deletions(-) create mode 100644 .github/workflows/commitlint.yml create mode 100644 .github/workflows/release.yml rename .prettierrc => .prettierrc.yml (100%) create mode 100644 RELEASING.md create mode 100644 example/del-keys-without-ttl/README.md create mode 100644 example/del-keys-without-ttl/go.mod rename {extra/redisotel/example => example/del-keys-without-ttl}/go.sum (56%) create mode 100644 example/del-keys-without-ttl/main.go create mode 100644 example/hll/README.md create mode 100644 example/hll/go.mod create mode 100644 example/hll/go.sum create mode 100644 example/hll/main.go create mode 100644 example/lua-scripting/README.md create mode 100644 example/lua-scripting/go.mod create mode 100644 example/lua-scripting/go.sum create mode 100644 example/lua-scripting/main.go delete mode 100644 example/otel/example-client.go create mode 100644 example/otel/main.go create mode 100644 example/redis-bloom/README.md create mode 100644 example/redis-bloom/go.mod create mode 100644 example/redis-bloom/go.sum create mode 100644 example/redis-bloom/main.go create mode 100644 example/scan-struct/README.md create mode 100644 example/scan-struct/go.mod create mode 100644 example/scan-struct/go.sum create mode 100644 example/scan-struct/main.go delete mode 100644 extra/redisotel/example/Makefile delete mode 100644 extra/redisotel/example/README.md delete mode 100644 extra/redisotel/example/docker-compose.yml delete mode 100644 extra/redisotel/example/go.mod delete mode 100644 extra/redisotel/example/main.go create mode 100644 extra/redisotel/redisotel_test.go delete mode 100644 internal/pool/conncheck.go delete mode 100644 internal/pool/conncheck_dummy.go delete mode 100644 internal/pool/conncheck_test.go create mode 100644 package.json create mode 100755 scripts/bump_deps.sh create mode 100755 scripts/release.sh create mode 100755 scripts/tag.sh create mode 100644 version.go diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index caef4b31bb..707670d0fa 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -custom: ['https://uptrace.dev'] +custom: ['https://uptrace.dev/sponsor'] diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index fbaa570b42..e86d7a6672 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -3,6 +3,3 @@ contact_links: - name: Discussions url: https://github.com/go-redis/redis/discussions about: Ask a question via GitHub Discussions - - name: Discord - url: https://discord.gg/rWtp5Aj - about: Ask a question via Discord diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 59ee91cb75..32dc68680e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,8 +11,9 @@ jobs: name: build runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - go-version: [1.15.x, 1.16.x] + go-version: [1.16.x, 1.17.x] services: redis: @@ -29,7 +30,7 @@ jobs: go-version: ${{ matrix.go-version }} - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Test run: make test diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 0000000000..5fcfeaea7b --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,11 @@ +name: Lint Commit Messages +on: [pull_request] + +jobs: + commitlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: wagoid/commitlint-github-action@v4 diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 1d9708c0ab..91c4b53ecf 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -15,6 +15,6 @@ jobs: name: lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: golangci-lint uses: golangci/golangci-lint-action@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..685693ae7c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,17 @@ +name: Releases + +on: + push: + tags: + - 'v*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ncipollo/release-action@v1 + with: + body: + Please refer to + [CHANGELOG.md](https://github.com/go-redis/redis/blob/master/CHANGELOG.md) for details diff --git a/.golangci.yml b/.golangci.yml index d15b5ac587..de514554a9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,25 +2,3 @@ run: concurrency: 8 deadline: 5m tests: false -linters: - enable-all: true - disable: - - funlen - - gochecknoglobals - - gochecknoinits - - gocognit - - goconst - - godox - - gosec - - maligned - - wsl - - gomnd - - goerr113 - - exhaustive - - nestif - - nlreturn - - exhaustivestruct - - wrapcheck - - errorlint - - cyclop - - forcetypeassert diff --git a/.prettierrc b/.prettierrc.yml similarity index 100% rename from .prettierrc rename to .prettierrc.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index c6c62602ec..83fcbe2aef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,41 @@ -# Changelog +## [8.11.5](https://github.com/go-redis/redis/compare/v8.11.4...v8.11.5) (2022-03-17) + + +### Bug Fixes + +* add missing Expire methods to Cmdable ([17e3b43](https://github.com/go-redis/redis/commit/17e3b43879d516437ada71cf9c0deac6a382ed9a)) +* add whitespace for avoid unlikely colisions ([7f7c181](https://github.com/go-redis/redis/commit/7f7c1817617cfec909efb13d14ad22ef05a6ad4c)) +* example/otel compile error ([#2028](https://github.com/go-redis/redis/issues/2028)) ([187c07c](https://github.com/go-redis/redis/commit/187c07c41bf68dc3ab280bc3a925e960bbef6475)) +* **extra/redisotel:** set span.kind attribute to client ([065b200](https://github.com/go-redis/redis/commit/065b200070b41e6e949710b4f9e01b50ccc60ab2)) +* format ([96f53a0](https://github.com/go-redis/redis/commit/96f53a0159a28affa94beec1543a62234e7f8b32)) +* invalid type assert in stringArg ([de6c131](https://github.com/go-redis/redis/commit/de6c131865b8263400c8491777b295035f2408e4)) +* rename Golang to Go ([#2030](https://github.com/go-redis/redis/issues/2030)) ([b82a2d9](https://github.com/go-redis/redis/commit/b82a2d9d4d2de7b7cbe8fcd4895be62dbcacacbc)) +* set timeout for WAIT command. Fixes [#1963](https://github.com/go-redis/redis/issues/1963) ([333fee1](https://github.com/go-redis/redis/commit/333fee1a8fd98a2fbff1ab187c1b03246a7eb01f)) +* update some argument counts in pre-allocs ([f6974eb](https://github.com/go-redis/redis/commit/f6974ebb5c40a8adf90d2cacab6dc297f4eba4c2)) + + +### Features + +* Add redis v7's NX, XX, GT, LT expire variants ([e19bbb2](https://github.com/go-redis/redis/commit/e19bbb26e2e395c6e077b48d80d79e99f729a8b8)) +* add support for acl sentinel auth in universal client ([ab0ccc4](https://github.com/go-redis/redis/commit/ab0ccc47413f9b2a6eabc852fed5005a3ee1af6e)) +* add support for COPY command ([#2016](https://github.com/go-redis/redis/issues/2016)) ([730afbc](https://github.com/go-redis/redis/commit/730afbcffb93760e8a36cc06cfe55ab102b693a7)) +* add support for passing extra attributes added to spans ([39faaa1](https://github.com/go-redis/redis/commit/39faaa171523834ba527c9789710c4fde87f5a2e)) +* add support for time.Duration write and scan ([2f1b74e](https://github.com/go-redis/redis/commit/2f1b74e20cdd7719b2aecf0768d3e3ae7c3e781b)) +* **redisotel:** ability to override TracerProvider ([#1998](https://github.com/go-redis/redis/issues/1998)) ([bf8d4aa](https://github.com/go-redis/redis/commit/bf8d4aa60c00366cda2e98c3ddddc8cf68507417)) +* set net.peer.name and net.peer.port in otel example ([69bf454](https://github.com/go-redis/redis/commit/69bf454f706204211cd34835f76b2e8192d3766d)) + + + +## [8.11.4](https://github.com/go-redis/redis/compare/v8.11.3...v8.11.4) (2021-10-04) + + +### Features + +* add acl auth support for sentinels ([f66582f](https://github.com/go-redis/redis/commit/f66582f44f3dc3a4705a5260f982043fde4aa634)) +* add Cmd.{String,Int,Float,Bool}Slice helpers and an example ([5d3d293](https://github.com/go-redis/redis/commit/5d3d293cc9c60b90871e2420602001463708ce24)) +* add SetVal method for each command ([168981d](https://github.com/go-redis/redis/commit/168981da2d84ee9e07d15d3e74d738c162e264c4)) + -> :heart: -> [**Uptrace.dev** - All-in-one tool to optimize performance and monitor errors & logs](https://uptrace.dev) ## v9 UNRELEASED diff --git a/Makefile b/Makefile index b16709c8c5..a4cfe0576e 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +PACKAGE_DIRS := $(shell find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; | sort) + test: testdeps go test ./... go test ./... -short -race @@ -19,8 +21,15 @@ testdata/redis: testdata/redis/src/redis-server: testdata/redis cd $< && make all -tag: - git tag $(VERSION) - git tag extra/rediscmd/$(VERSION) - git tag extra/redisotel/$(VERSION) - git tag extra/rediscensus/$(VERSION) +fmt: + gofmt -w -s ./ + goimports -w -local github.com/go-redis/redis ./ + +go_mod_tidy: + go get -u && go mod tidy + set -e; for dir in $(PACKAGE_DIRS); do \ + echo "go mod tidy in $${dir}"; \ + (cd "$${dir}" && \ + go get -u && \ + go mod tidy); \ + done diff --git a/README.md b/README.md index 2c36f786f8..2fffbc005b 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,33 @@ -

- - All-in-one tool to optimize performance and monitor errors & logs - -

- -# Redis client for Golang +# Redis client for Go ![build workflow](https://github.com/go-redis/redis/actions/workflows/build.yml/badge.svg) [![PkgGoDev](https://pkg.go.dev/badge/github.com/go-redis/redis/v8)](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc) [![Documentation](https://img.shields.io/badge/redis-documentation-informational)](https://redis.uptrace.dev/) [![Chat](https://discordapp.com/api/guilds/752070105847955518/widget.png)](https://discord.gg/rWtp5Aj) -- Join [Discord](https://discord.gg/rWtp5Aj) to ask questions. +go-redis is brought to you by :star: [**uptrace/uptrace**](https://github.com/uptrace/uptrace). +Uptrace is an open source and blazingly fast **distributed tracing** backend powered by +OpenTelemetry and ClickHouse. Give it a star as well! + +## Resources + +- [Discussions](https://github.com/go-redis/redis/discussions) - [Documentation](https://redis.uptrace.dev) - [Reference](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc) - [Examples](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#pkg-examples) - [RealWorld example app](https://github.com/uptrace/go-treemux-realworld-example-app) -My other projects: +Other projects you may like: - [Bun](https://bun.uptrace.dev) - fast and simple SQL client for PostgreSQL, MySQL, and SQLite. -- [treemux](https://github.com/vmihailenco/treemux) - high-speed, flexible, tree-based HTTP router - for Go. +- [BunRouter](https://bunrouter.uptrace.dev/) - fast and flexible HTTP router for Go. ## Ecosystem -- [Redis Mock](https://github.com/go-redis/redismock). -- [Distributed Locks](https://github.com/bsm/redislock). -- [Redis Cache](https://github.com/go-redis/cache). -- [Rate limiting](https://github.com/go-redis/redis_rate). +- [Redis Mock](https://github.com/go-redis/redismock) +- [Distributed Locks](https://github.com/bsm/redislock) +- [Redis Cache](https://github.com/go-redis/cache) +- [Rate limiting](https://github.com/go-redis/redis_rate) ## Features @@ -37,16 +36,16 @@ My other projects: [circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) support. - [Pub/Sub](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#PubSub). - [Transactions](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline). -- [Pipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-Pipeline) and - [TxPipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline). +- [Pipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client.Pipeline) and + [TxPipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client.TxPipeline). - [Scripting](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Script). - [Timeouts](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options). - [Redis Sentinel](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewFailoverClient). - [Redis Cluster](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewClusterClient). -- [Cluster of Redis Servers](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-NewClusterClient--ManualSetup) +- [Cluster of Redis Servers](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-NewClusterClient-ManualSetup) without using cluster mode and Redis Sentinel. - [Ring](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewRing). -- [Instrumentation](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#ex-package--Instrumentation). +- [Instrumentation](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-package-Instrumentation). ## Installation @@ -70,6 +69,7 @@ go get github.com/go-redis/redis/v8 import ( "context" "github.com/go-redis/redis/v8" + "fmt" ) var ctx = context.Background() diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000000..1115db4e3e --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,15 @@ +# Releasing + +1. Run `release.sh` script which updates versions in go.mod files and pushes a new branch to GitHub: + +```shell +TAG=v1.0.0 ./scripts/release.sh +``` + +2. Open a pull request and wait for the build to finish. + +3. Merge the pull request and run `tag.sh` to create tags for packages: + +```shell +TAG=v1.0.0 ./scripts/tag.sh +``` diff --git a/bench_test.go b/bench_test.go index 0f26152dbf..df43d89010 100644 --- a/bench_test.go +++ b/bench_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "strconv" "strings" "sync" "testing" @@ -233,6 +234,45 @@ func BenchmarkZAdd(b *testing.B) { }) } +func BenchmarkXRead(b *testing.B) { + ctx := context.Background() + client := benchmarkRedisClient(ctx, 10) + defer client.Close() + + args := redis.XAddArgs{ + Stream: "1", + ID: "*", + Values: map[string]string{"uno": "dos"}, + } + + lenStreams := 16 + streams := make([]string, 0, lenStreams) + for i := 0; i < lenStreams; i++ { + streams = append(streams, strconv.Itoa(i)) + } + for i := 0; i < lenStreams; i++ { + streams = append(streams, "0") + } + + b.ReportAllocs() + b.ResetTimer() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + client.XAdd(ctx, &args) + + err := client.XRead(ctx, &redis.XReadArgs{ + Streams: streams, + Count: 1, + Block: time.Second, + }).Err() + if err != nil { + b.Fatal(err) + } + } + }) +} + var clientSink *redis.Client func BenchmarkWithContext(b *testing.B) { @@ -301,6 +341,32 @@ func BenchmarkClusterPing(b *testing.B) { }) } +func BenchmarkClusterDoInt(b *testing.B) { + if testing.Short() { + b.Skip("skipping in short mode") + } + + ctx := context.Background() + cluster := newClusterScenario() + if err := startCluster(ctx, cluster); err != nil { + b.Fatal(err) + } + defer cluster.Close() + + client := cluster.newClusterClient(ctx, redisClusterOptions()) + defer client.Close() + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + err := client.Do(ctx, "SET", 10, 10).Err() + if err != nil { + b.Fatal(err) + } + } + }) +} + func BenchmarkClusterSetString(b *testing.B) { if testing.Short() { b.Skip("skipping in short mode") diff --git a/cluster.go b/cluster.go index bfc7d4e51b..27dd31b38f 100644 --- a/cluster.go +++ b/cluster.go @@ -352,7 +352,7 @@ func (c *clusterNodes) GC(generation uint32) { } } -func (c *clusterNodes) Get(addr string) (*clusterNode, error) { +func (c *clusterNodes) GetOrCreate(addr string) (*clusterNode, error) { node, err := c.get(addr) if err != nil { return nil, err @@ -416,7 +416,7 @@ func (c *clusterNodes) Random() (*clusterNode, error) { } n := rand.Intn(len(addrs)) - return c.Get(addrs[n]) + return c.GetOrCreate(addrs[n]) } //------------------------------------------------------------------------------ @@ -474,7 +474,7 @@ func newClusterState( addr = replaceLoopbackHost(addr, originHost) } - node, err := c.nodes.Get(addr) + node, err := c.nodes.GetOrCreate(addr) if err != nil { return nil, err } @@ -823,8 +823,10 @@ func (c *ClusterClient) process(ctx context.Context, cmd Cmder) error { var addr string moved, ask, addr = isMovedError(lastErr) if moved || ask { + c.state.LazyReload() + var err error - node, err = c.nodes.Get(addr) + node, err = c.nodes.GetOrCreate(addr) if err != nil { return err } @@ -1021,7 +1023,7 @@ func (c *ClusterClient) loadState(ctx context.Context) (*clusterState, error) { for _, idx := range rand.Perm(len(addrs)) { addr := addrs[idx] - node, err := c.nodes.Get(addr) + node, err := c.nodes.GetOrCreate(addr) if err != nil { if firstErr == nil { firstErr = err @@ -1235,7 +1237,7 @@ func (c *ClusterClient) checkMovedErr( return false } - node, err := c.nodes.Get(addr) + node, err := c.nodes.GetOrCreate(addr) if err != nil { return false } @@ -1416,7 +1418,7 @@ func (c *ClusterClient) cmdsMoved( addr string, failedCmds *cmdsMap, ) error { - node, err := c.nodes.Get(addr) + node, err := c.nodes.GetOrCreate(addr) if err != nil { return err } @@ -1471,7 +1473,7 @@ func (c *ClusterClient) Watch(ctx context.Context, fn func(*Tx) error, keys ...s moved, ask, addr := isMovedError(err) if moved || ask { - node, err = c.nodes.Get(addr) + node, err = c.nodes.GetOrCreate(addr) if err != nil { return err } @@ -1583,7 +1585,7 @@ func (c *ClusterClient) cmdsInfo(ctx context.Context) (map[string]*CommandInfo, for _, idx := range perm { addr := addrs[idx] - node, err := c.nodes.Get(addr) + node, err := c.nodes.GetOrCreate(addr) if err != nil { if firstErr == nil { firstErr = err diff --git a/cluster_test.go b/cluster_test.go index fa69262049..2d2021cf53 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -9,11 +9,11 @@ import ( "sync" "time" - "github.com/go-redis/redis/v8" - "github.com/go-redis/redis/v8/internal/hashtag" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v8/internal/hashtag" ) type clusterScenario struct { diff --git a/command.go b/command.go index d1be104324..810dededd4 100644 --- a/command.go +++ b/command.go @@ -20,7 +20,7 @@ type Cmder interface { String() string stringArg(int) string firstKeyPos() int8 - setFirstKeyPos(int8) + SetFirstKeyPos(int8) readTimeout() *time.Duration readReply(rd *proto.Reader) error @@ -151,15 +151,21 @@ func (cmd *baseCmd) stringArg(pos int) string { if pos < 0 || pos >= len(cmd.args) { return "" } - s, _ := cmd.args[pos].(string) - return s + arg := cmd.args[pos] + switch v := arg.(type) { + case string: + return v + default: + // TODO: consider using appendArg + return fmt.Sprint(v) + } } func (cmd *baseCmd) firstKeyPos() int8 { return cmd.keyPos } -func (cmd *baseCmd) setFirstKeyPos(keyPos int8) { +func (cmd *baseCmd) SetFirstKeyPos(keyPos int8) { cmd.keyPos = keyPos } @@ -200,6 +206,10 @@ func (cmd *Cmd) String() string { return cmdString(cmd, cmd.val) } +func (cmd *Cmd) SetVal(val interface{}) { + cmd.val = val +} + func (cmd *Cmd) Val() interface{} { return cmd.val } @@ -212,7 +222,11 @@ func (cmd *Cmd) Text() (string, error) { if cmd.err != nil { return "", cmd.err } - switch val := cmd.val.(type) { + return toString(cmd.val) +} + +func toString(val interface{}) (string, error) { + switch val := val.(type) { case string: return val, nil default: @@ -240,7 +254,11 @@ func (cmd *Cmd) Int64() (int64, error) { if cmd.err != nil { return 0, cmd.err } - switch val := cmd.val.(type) { + return toInt64(cmd.val) +} + +func toInt64(val interface{}) (int64, error) { + switch val := val.(type) { case int64: return val, nil case string: @@ -255,7 +273,11 @@ func (cmd *Cmd) Uint64() (uint64, error) { if cmd.err != nil { return 0, cmd.err } - switch val := cmd.val.(type) { + return toUint64(cmd.val) +} + +func toUint64(val interface{}) (uint64, error) { + switch val := val.(type) { case int64: return uint64(val), nil case string: @@ -270,7 +292,11 @@ func (cmd *Cmd) Float32() (float32, error) { if cmd.err != nil { return 0, cmd.err } - switch val := cmd.val.(type) { + return toFloat32(cmd.val) +} + +func toFloat32(val interface{}) (float32, error) { + switch val := val.(type) { case int64: return float32(val), nil case string: @@ -289,7 +315,11 @@ func (cmd *Cmd) Float64() (float64, error) { if cmd.err != nil { return 0, cmd.err } - switch val := cmd.val.(type) { + return toFloat64(cmd.val) +} + +func toFloat64(val interface{}) (float64, error) { + switch val := val.(type) { case int64: return float64(val), nil case string: @@ -304,7 +334,11 @@ func (cmd *Cmd) Bool() (bool, error) { if cmd.err != nil { return false, cmd.err } - switch val := cmd.val.(type) { + return toBool(cmd.val) +} + +func toBool(val interface{}) (bool, error) { + switch val := val.(type) { case int64: return val != 0, nil case string: @@ -315,6 +349,120 @@ func (cmd *Cmd) Bool() (bool, error) { } } +func (cmd *Cmd) Slice() ([]interface{}, error) { + if cmd.err != nil { + return nil, cmd.err + } + switch val := cmd.val.(type) { + case []interface{}: + return val, nil + default: + return nil, fmt.Errorf("redis: unexpected type=%T for Slice", val) + } +} + +func (cmd *Cmd) StringSlice() ([]string, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + ss := make([]string, len(slice)) + for i, iface := range slice { + val, err := toString(iface) + if err != nil { + return nil, err + } + ss[i] = val + } + return ss, nil +} + +func (cmd *Cmd) Int64Slice() ([]int64, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + nums := make([]int64, len(slice)) + for i, iface := range slice { + val, err := toInt64(iface) + if err != nil { + return nil, err + } + nums[i] = val + } + return nums, nil +} + +func (cmd *Cmd) Uint64Slice() ([]uint64, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + nums := make([]uint64, len(slice)) + for i, iface := range slice { + val, err := toUint64(iface) + if err != nil { + return nil, err + } + nums[i] = val + } + return nums, nil +} + +func (cmd *Cmd) Float32Slice() ([]float32, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + floats := make([]float32, len(slice)) + for i, iface := range slice { + val, err := toFloat32(iface) + if err != nil { + return nil, err + } + floats[i] = val + } + return floats, nil +} + +func (cmd *Cmd) Float64Slice() ([]float64, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + floats := make([]float64, len(slice)) + for i, iface := range slice { + val, err := toFloat64(iface) + if err != nil { + return nil, err + } + floats[i] = val + } + return floats, nil +} + +func (cmd *Cmd) BoolSlice() ([]bool, error) { + slice, err := cmd.Slice() + if err != nil { + return nil, err + } + + bools := make([]bool, len(slice)) + for i, iface := range slice { + val, err := toBool(iface) + if err != nil { + return nil, err + } + bools[i] = val + } + return bools, nil +} + func (cmd *Cmd) readReply(rd *proto.Reader) (err error) { cmd.val, err = rd.ReadReply() return err @@ -339,6 +487,10 @@ func NewSliceCmd(ctx context.Context, args ...interface{}) *SliceCmd { } } +func (cmd *SliceCmd) SetVal(val []interface{}) { + cmd.val = val +} + func (cmd *SliceCmd) Val() []interface{} { return cmd.val } @@ -395,6 +547,10 @@ func NewStatusCmd(ctx context.Context, args ...interface{}) *StatusCmd { } } +func (cmd *StatusCmd) SetVal(val string) { + cmd.val = val +} + func (cmd *StatusCmd) Val() string { return cmd.val } @@ -431,6 +587,10 @@ func NewIntCmd(ctx context.Context, args ...interface{}) *IntCmd { } } +func (cmd *IntCmd) SetVal(val int64) { + cmd.val = val +} + func (cmd *IntCmd) Val() int64 { return cmd.val } @@ -471,6 +631,10 @@ func NewIntSliceCmd(ctx context.Context, args ...interface{}) *IntSliceCmd { } } +func (cmd *IntSliceCmd) SetVal(val []int64) { + cmd.val = val +} + func (cmd *IntSliceCmd) Val() []int64 { return cmd.val } @@ -518,6 +682,10 @@ func NewDurationCmd(ctx context.Context, precision time.Duration, args ...interf } } +func (cmd *DurationCmd) SetVal(val time.Duration) { + cmd.val = val +} + func (cmd *DurationCmd) Val() time.Duration { return cmd.val } @@ -565,6 +733,10 @@ func NewTimeCmd(ctx context.Context, args ...interface{}) *TimeCmd { } } +func (cmd *TimeCmd) SetVal(val time.Time) { + cmd.val = val +} + func (cmd *TimeCmd) Val() time.Time { return cmd.val } @@ -612,6 +784,10 @@ func NewBoolCmd(ctx context.Context, args ...interface{}) *BoolCmd { } } +func (cmd *BoolCmd) SetVal(val bool) { + cmd.val = val +} + func (cmd *BoolCmd) Val() bool { return cmd.val } @@ -655,6 +831,10 @@ func NewStringCmd(ctx context.Context, args ...interface{}) *StringCmd { } } +func (cmd *StringCmd) SetVal(val string) { + cmd.val = val +} + func (cmd *StringCmd) Val() string { return cmd.val } @@ -755,6 +935,10 @@ func NewFloatCmd(ctx context.Context, args ...interface{}) *FloatCmd { } } +func (cmd *FloatCmd) SetVal(val float64) { + cmd.val = val +} + func (cmd *FloatCmd) Val() float64 { return cmd.val } @@ -791,6 +975,10 @@ func NewFloatSliceCmd(ctx context.Context, args ...interface{}) *FloatSliceCmd { } } +func (cmd *FloatSliceCmd) SetVal(val []float64) { + cmd.val = val +} + func (cmd *FloatSliceCmd) Val() []float64 { return cmd.val } @@ -842,6 +1030,10 @@ func NewStringSliceCmd(ctx context.Context, args ...interface{}) *StringSliceCmd } } +func (cmd *StringSliceCmd) SetVal(val []string) { + cmd.val = val +} + func (cmd *StringSliceCmd) Val() []string { return cmd.val } @@ -985,6 +1177,10 @@ func NewBoolSliceCmd(ctx context.Context, args ...interface{}) *BoolSliceCmd { } } +func (cmd *BoolSliceCmd) SetVal(val []bool) { + cmd.val = val +} + func (cmd *BoolSliceCmd) Val() []bool { return cmd.val } @@ -1034,6 +1230,10 @@ func (cmd *MapStringStringCmd) Val() map[string]string { return cmd.val } +func (cmd *MapStringStringCmd) SetVal(val map[string]string) { + cmd.val = val +} + func (cmd *MapStringStringCmd) Result() (map[string]string, error) { return cmd.val, cmd.err } @@ -1044,12 +1244,12 @@ func (cmd *MapStringStringCmd) String() string { // Scan scans the results from the map into a destination struct. The map keys // are matched in the Redis struct fields by the `redis:"field"` tag. -func (cmd *MapStringStringCmd) Scan(dst interface{}) error { +func (cmd *MapStringStringCmd) Scan(dest interface{}) error { if cmd.err != nil { return cmd.err } - strct, err := hscan.Struct(dst) + strct, err := hscan.Struct(dest) if err != nil { return err } @@ -1105,6 +1305,10 @@ func NewStringIntMapCmd(ctx context.Context, args ...interface{}) *StringIntMapC } } +func (cmd *StringIntMapCmd) SetVal(val map[string]int64) { + cmd.val = val +} + func (cmd *StringIntMapCmd) Val() map[string]int64 { return cmd.val } @@ -1158,6 +1362,10 @@ func NewStringStructMapCmd(ctx context.Context, args ...interface{}) *StringStru } } +func (cmd *StringStructMapCmd) SetVal(val map[string]struct{}) { + cmd.val = val +} + func (cmd *StringStructMapCmd) Val() map[string]struct{} { return cmd.val } @@ -1211,6 +1419,10 @@ func NewXMessageSliceCmd(ctx context.Context, args ...interface{}) *XMessageSlic } } +func (cmd *XMessageSliceCmd) SetVal(val []XMessage) { + cmd.val = val +} + func (cmd *XMessageSliceCmd) Val() []XMessage { return cmd.val } @@ -1313,6 +1525,10 @@ func NewXStreamSliceCmd(ctx context.Context, args ...interface{}) *XStreamSliceC } } +func (cmd *XStreamSliceCmd) SetVal(val []XStream) { + cmd.val = val +} + func (cmd *XStreamSliceCmd) Val() []XStream { return cmd.val } @@ -1382,6 +1598,10 @@ func NewXPendingCmd(ctx context.Context, args ...interface{}) *XPendingCmd { } } +func (cmd *XPendingCmd) SetVal(val *XPending) { + cmd.val = val +} + func (cmd *XPendingCmd) Val() *XPending { return cmd.val } @@ -1461,6 +1681,10 @@ func NewXPendingExtCmd(ctx context.Context, args ...interface{}) *XPendingExtCmd } } +func (cmd *XPendingExtCmd) SetVal(val []XPendingExt) { + cmd.val = val +} + func (cmd *XPendingExtCmd) Val() []XPendingExt { return cmd.val } @@ -1527,6 +1751,11 @@ func NewXAutoClaimCmd(ctx context.Context, args ...interface{}) *XAutoClaimCmd { } } +func (cmd *XAutoClaimCmd) SetVal(val []XMessage, start string) { + cmd.val = val + cmd.start = start +} + func (cmd *XAutoClaimCmd) Val() (messages []XMessage, start string) { return cmd.val, cmd.start } @@ -1576,6 +1805,11 @@ func NewXAutoClaimJustIDCmd(ctx context.Context, args ...interface{}) *XAutoClai } } +func (cmd *XAutoClaimJustIDCmd) SetVal(val []string, start string) { + cmd.val = val + cmd.start = start +} + func (cmd *XAutoClaimJustIDCmd) Val() (ids []string, start string) { return cmd.val, cmd.start } @@ -1637,6 +1871,10 @@ func NewXInfoConsumersCmd(ctx context.Context, stream string, group string) *XIn } } +func (cmd *XInfoConsumersCmd) SetVal(val []XInfoConsumer) { + cmd.val = val +} + func (cmd *XInfoConsumersCmd) Val() []XInfoConsumer { return cmd.val } @@ -1712,6 +1950,10 @@ func NewXInfoGroupsCmd(ctx context.Context, stream string) *XInfoGroupsCmd { } } +func (cmd *XInfoGroupsCmd) SetVal(val []XInfoGroup) { + cmd.val = val +} + func (cmd *XInfoGroupsCmd) Val() []XInfoGroup { return cmd.val } @@ -1792,6 +2034,10 @@ func NewXInfoStreamCmd(ctx context.Context, stream string) *XInfoStreamCmd { } } +func (cmd *XInfoStreamCmd) SetVal(val *XInfoStream) { + cmd.val = val +} + func (cmd *XInfoStreamCmd) Val() *XInfoStream { return cmd.val } @@ -1902,6 +2148,10 @@ func NewXInfoStreamFullCmd(ctx context.Context, args ...interface{}) *XInfoStrea } } +func (cmd *XInfoStreamFullCmd) SetVal(val *XInfoStreamFull) { + cmd.val = val +} + func (cmd *XInfoStreamFullCmd) Val() *XInfoStreamFull { return cmd.val } @@ -2137,6 +2387,10 @@ func NewZSliceCmd(ctx context.Context, args ...interface{}) *ZSliceCmd { } } +func (cmd *ZSliceCmd) SetVal(val []Z) { + cmd.val = val +} + func (cmd *ZSliceCmd) Val() []Z { return cmd.val } @@ -2211,6 +2465,10 @@ func NewZWithKeyCmd(ctx context.Context, args ...interface{}) *ZWithKeyCmd { } } +func (cmd *ZWithKeyCmd) SetVal(val *ZWithKey) { + cmd.val = val +} + func (cmd *ZWithKeyCmd) Val() *ZWithKey { return cmd.val } @@ -2265,6 +2523,11 @@ func NewScanCmd(ctx context.Context, process cmdable, args ...interface{}) *Scan } } +func (cmd *ScanCmd) SetVal(page []string, cursor uint64) { + cmd.page = page + cmd.cursor = cursor +} + func (cmd *ScanCmd) Val() (keys []string, cursor uint64) { return cmd.page, cmd.cursor } @@ -2339,6 +2602,10 @@ func NewClusterSlotsCmd(ctx context.Context, args ...interface{}) *ClusterSlotsC } } +func (cmd *ClusterSlotsCmd) SetVal(val []ClusterSlot) { + cmd.val = val +} + func (cmd *ClusterSlotsCmd) Val() []ClusterSlot { return cmd.val } @@ -2500,6 +2767,10 @@ func geoLocationArgs(q *GeoRadiusQuery, args ...interface{}) []interface{} { return args } +func (cmd *GeoLocationCmd) SetVal(locations []GeoLocation) { + cmd.locations = locations +} + func (cmd *GeoLocationCmd) Val() []GeoLocation { return cmd.locations } @@ -2762,6 +3033,10 @@ func NewGeoPosCmd(ctx context.Context, args ...interface{}) *GeoPosCmd { } } +func (cmd *GeoPosCmd) SetVal(val []*GeoPos) { + cmd.val = val +} + func (cmd *GeoPosCmd) Val() []*GeoPos { return cmd.val } @@ -2839,6 +3114,10 @@ func NewCommandsInfoCmd(ctx context.Context, args ...interface{}) *CommandsInfoC } } +func (cmd *CommandsInfoCmd) SetVal(val map[string]*CommandInfo) { + cmd.val = val +} + func (cmd *CommandsInfoCmd) Val() map[string]*CommandInfo { return cmd.val } @@ -3008,6 +3287,10 @@ func NewSlowLogCmd(ctx context.Context, args ...interface{}) *SlowLogCmd { } } +func (cmd *SlowLogCmd) SetVal(val []SlowLog) { + cmd.val = val +} + func (cmd *SlowLogCmd) Val() []SlowLog { return cmd.val } diff --git a/command_test.go b/command_test.go index 9877df4273..775987fc1a 100644 --- a/command_test.go +++ b/command_test.go @@ -72,7 +72,7 @@ var _ = Describe("Cmd", func() { }) It("supports time.Time", func() { - tm := time.Date(2019, 01, 01, 9, 45, 10, 222125, time.UTC) + tm := time.Date(2019, 1, 1, 9, 45, 10, 222125, time.UTC) err := client.Set(ctx, "time_key", tm, 0).Err() Expect(err).NotTo(HaveOccurred()) diff --git a/commands.go b/commands.go index b63aa0136d..eb0757d17c 100644 --- a/commands.go +++ b/commands.go @@ -96,6 +96,10 @@ type Cmdable interface { Exists(ctx context.Context, keys ...string) *IntCmd Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd ExpireAt(ctx context.Context, key string, tm time.Time) *BoolCmd + ExpireNX(ctx context.Context, key string, expiration time.Duration) *BoolCmd + ExpireXX(ctx context.Context, key string, expiration time.Duration) *BoolCmd + ExpireGT(ctx context.Context, key string, expiration time.Duration) *BoolCmd + ExpireLT(ctx context.Context, key string, expiration time.Duration) *BoolCmd Keys(ctx context.Context, pattern string) *StringSliceCmd Migrate(ctx context.Context, host, port, key string, db int, timeout time.Duration) *StatusCmd Move(ctx context.Context, key string, db int) *BoolCmd @@ -138,6 +142,7 @@ type Cmdable interface { SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd SetRange(ctx context.Context, key string, offset int64, value string) *IntCmd StrLen(ctx context.Context, key string) *IntCmd + Copy(ctx context.Context, sourceKey string, destKey string, db int, replace bool) *IntCmd GetBit(ctx context.Context, key string, offset int64) *IntCmd SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd @@ -195,6 +200,7 @@ type Cmdable interface { RPush(ctx context.Context, key string, values ...interface{}) *IntCmd RPushX(ctx context.Context, key string, values ...interface{}) *IntCmd LMove(ctx context.Context, source, destination, srcpos, destpos string) *StringCmd + BLMove(ctx context.Context, source, destination, srcpos, destpos string, timeout time.Duration) *StringCmd SAdd(ctx context.Context, key string, members ...interface{}) *IntCmd SCard(ctx context.Context, key string) *IntCmd @@ -415,6 +421,7 @@ func (c statefulCmdable) AuthACL(ctx context.Context, username, password string) func (c cmdable) Wait(ctx context.Context, numSlaves int, timeout time.Duration) *IntCmd { cmd := NewIntCmd(ctx, "wait", numSlaves, int(timeout/time.Millisecond)) + cmd.setReadTimeout(timeout) _ = c(ctx, cmd) return cmd } @@ -529,7 +536,37 @@ func (c cmdable) Exists(ctx context.Context, keys ...string) *IntCmd { } func (c cmdable) Expire(ctx context.Context, key string, expiration time.Duration) *BoolCmd { - cmd := NewBoolCmd(ctx, "expire", key, formatSec(ctx, expiration)) + return c.expire(ctx, key, expiration, "") +} + +func (c cmdable) ExpireNX(ctx context.Context, key string, expiration time.Duration) *BoolCmd { + return c.expire(ctx, key, expiration, "NX") +} + +func (c cmdable) ExpireXX(ctx context.Context, key string, expiration time.Duration) *BoolCmd { + return c.expire(ctx, key, expiration, "XX") +} + +func (c cmdable) ExpireGT(ctx context.Context, key string, expiration time.Duration) *BoolCmd { + return c.expire(ctx, key, expiration, "GT") +} + +func (c cmdable) ExpireLT(ctx context.Context, key string, expiration time.Duration) *BoolCmd { + return c.expire(ctx, key, expiration, "LT") +} + +func (c cmdable) expire( + ctx context.Context, key string, expiration time.Duration, mode string, +) *BoolCmd { + args := make([]interface{}, 3, 4) + args[0] = "expire" + args[1] = key + args[2] = formatSec(ctx, expiration) + if mode != "" { + args = append(args, mode) + } + + cmd := NewBoolCmd(ctx, args...) _ = c(ctx, cmd) return cmd } @@ -994,6 +1031,16 @@ func (c cmdable) StrLen(ctx context.Context, key string) *IntCmd { return cmd } +func (c cmdable) Copy(ctx context.Context, sourceKey, destKey string, db int, replace bool) *IntCmd { + args := []interface{}{"copy", sourceKey, destKey, "DB", db} + if replace { + args = append(args, "REPLACE") + } + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + //------------------------------------------------------------------------------ func (c cmdable) GetBit(ctx context.Context, key string, offset int64) *IntCmd { @@ -1498,6 +1545,15 @@ func (c cmdable) LMove(ctx context.Context, source, destination, srcpos, destpos return cmd } +func (c cmdable) BLMove( + ctx context.Context, source, destination, srcpos, destpos string, timeout time.Duration, +) *StringCmd { + cmd := NewStringCmd(ctx, "blmove", source, destination, srcpos, destpos, formatSec(ctx, timeout)) + cmd.setReadTimeout(timeout) + _ = c(ctx, cmd) + return cmd +} + //------------------------------------------------------------------------------ func (c cmdable) SAdd(ctx context.Context, key string, members ...interface{}) *IntCmd { @@ -1765,7 +1821,7 @@ type XReadArgs struct { } func (c cmdable) XRead(ctx context.Context, a *XReadArgs) *XStreamSliceCmd { - args := make([]interface{}, 0, 5+len(a.Streams)) + args := make([]interface{}, 0, 6+len(a.Streams)) args = append(args, "xread") keyPos := int8(1) @@ -1789,7 +1845,7 @@ func (c cmdable) XRead(ctx context.Context, a *XReadArgs) *XStreamSliceCmd { if a.Block >= 0 { cmd.setReadTimeout(a.Block) } - cmd.setFirstKeyPos(keyPos) + cmd.SetFirstKeyPos(keyPos) _ = c(ctx, cmd) return cmd } @@ -1847,7 +1903,7 @@ type XReadGroupArgs struct { } func (c cmdable) XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSliceCmd { - args := make([]interface{}, 0, 8+len(a.Streams)) + args := make([]interface{}, 0, 10+len(a.Streams)) args = append(args, "xreadgroup", "group", a.Group, a.Consumer) keyPos := int8(4) @@ -1873,7 +1929,7 @@ func (c cmdable) XReadGroup(ctx context.Context, a *XReadGroupArgs) *XStreamSlic if a.Block >= 0 { cmd.setReadTimeout(a.Block) } - cmd.setFirstKeyPos(keyPos) + cmd.SetFirstKeyPos(keyPos) _ = c(ctx, cmd) return cmd } @@ -1944,7 +2000,7 @@ func (c cmdable) XAutoClaimJustID(ctx context.Context, a *XAutoClaimArgs) *XAuto } func xAutoClaimArgs(ctx context.Context, a *XAutoClaimArgs) []interface{} { - args := make([]interface{}, 0, 9) + args := make([]interface{}, 0, 8) args = append(args, "xautoclaim", a.Stream, a.Group, a.Consumer, formatMs(ctx, a.MinIdle), a.Start) if a.Count > 0 { args = append(args, "count", a.Count) @@ -1976,7 +2032,7 @@ func (c cmdable) XClaimJustID(ctx context.Context, a *XClaimArgs) *StringSliceCm } func xClaimArgs(a *XClaimArgs) []interface{} { - args := make([]interface{}, 0, 4+len(a.Messages)) + args := make([]interface{}, 0, 5+len(a.Messages)) args = append(args, "xclaim", a.Stream, @@ -2249,7 +2305,7 @@ func (c cmdable) ZInterStore(ctx context.Context, destination string, store *ZSt args = append(args, "zinterstore", destination, len(store.Keys)) args = store.appendArgs(args) cmd := NewIntCmd(ctx, args...) - cmd.setFirstKeyPos(3) + cmd.SetFirstKeyPos(3) _ = c(ctx, cmd) return cmd } @@ -2259,7 +2315,7 @@ func (c cmdable) ZInter(ctx context.Context, store *ZStore) *StringSliceCmd { args = append(args, "zinter", len(store.Keys)) args = store.appendArgs(args) cmd := NewStringSliceCmd(ctx, args...) - cmd.setFirstKeyPos(2) + cmd.SetFirstKeyPos(2) _ = c(ctx, cmd) return cmd } @@ -2270,7 +2326,7 @@ func (c cmdable) ZInterWithScores(ctx context.Context, store *ZStore) *ZSliceCmd args = store.appendArgs(args) args = append(args, "withscores") cmd := NewZSliceCmd(ctx, args...) - cmd.setFirstKeyPos(2) + cmd.SetFirstKeyPos(2) _ = c(ctx, cmd) return cmd } @@ -2597,7 +2653,7 @@ func (c cmdable) ZUnion(ctx context.Context, store ZStore) *StringSliceCmd { args = append(args, "zunion", len(store.Keys)) args = store.appendArgs(args) cmd := NewStringSliceCmd(ctx, args...) - cmd.setFirstKeyPos(2) + cmd.SetFirstKeyPos(2) _ = c(ctx, cmd) return cmd } @@ -2608,7 +2664,7 @@ func (c cmdable) ZUnionWithScores(ctx context.Context, store ZStore) *ZSliceCmd args = store.appendArgs(args) args = append(args, "withscores") cmd := NewZSliceCmd(ctx, args...) - cmd.setFirstKeyPos(2) + cmd.SetFirstKeyPos(2) _ = c(ctx, cmd) return cmd } @@ -2618,7 +2674,7 @@ func (c cmdable) ZUnionStore(ctx context.Context, dest string, store *ZStore) *I args = append(args, "zunionstore", dest, len(store.Keys)) args = store.appendArgs(args) cmd := NewIntCmd(ctx, args...) - cmd.setFirstKeyPos(3) + cmd.SetFirstKeyPos(3) _ = c(ctx, cmd) return cmd } @@ -2647,7 +2703,7 @@ func (c cmdable) ZDiff(ctx context.Context, keys ...string) *StringSliceCmd { } cmd := NewStringSliceCmd(ctx, args...) - cmd.setFirstKeyPos(2) + cmd.SetFirstKeyPos(2) _ = c(ctx, cmd) return cmd } @@ -2663,7 +2719,7 @@ func (c cmdable) ZDiffWithScores(ctx context.Context, keys ...string) *ZSliceCmd args[len(keys)+2] = "withscores" cmd := NewZSliceCmd(ctx, args...) - cmd.setFirstKeyPos(2) + cmd.SetFirstKeyPos(2) _ = c(ctx, cmd) return cmd } @@ -2939,7 +2995,7 @@ func (c cmdable) MemoryUsage(ctx context.Context, key string, samples ...int) *I args = append(args, "SAMPLES", samples[0]) } cmd := NewIntCmd(ctx, args...) - cmd.setFirstKeyPos(2) + cmd.SetFirstKeyPos(2) _ = c(ctx, cmd) return cmd } @@ -2956,7 +3012,7 @@ func (c cmdable) Eval(ctx context.Context, script string, keys []string, args .. } cmdArgs = appendArgs(cmdArgs, args) cmd := NewCmd(ctx, cmdArgs...) - cmd.setFirstKeyPos(3) + cmd.SetFirstKeyPos(3) _ = c(ctx, cmd) return cmd } @@ -2971,7 +3027,7 @@ func (c cmdable) EvalSha(ctx context.Context, sha1 string, keys []string, args . } cmdArgs = appendArgs(cmdArgs, args) cmd := NewCmd(ctx, cmdArgs...) - cmd.setFirstKeyPos(3) + cmd.SetFirstKeyPos(3) _ = c(ctx, cmd) return cmd } diff --git a/commands_test.go b/commands_test.go index 06d6e40184..81c1bdb878 100644 --- a/commands_test.go +++ b/commands_test.go @@ -484,11 +484,11 @@ var _ = Describe("Commands", func() { idleTime := client.ObjectIdleTime(ctx, "key") Expect(idleTime.Err()).NotTo(HaveOccurred()) - //Redis returned milliseconds/1000, which may cause ObjectIdleTime to be at a critical value, - //should be +1s to deal with the critical value problem. - //if too much time (>1s) is used during command execution, it may also cause the test to fail. - //so the ObjectIdleTime result should be <=now-start+1s - //link: https://github.com/redis/redis/blob/5b48d900498c85bbf4772c1d466c214439888115/src/object.c#L1265-L1272 + // Redis returned milliseconds/1000, which may cause ObjectIdleTime to be at a critical value, + // should be +1s to deal with the critical value problem. + // if too much time (>1s) is used during command execution, it may also cause the test to fail. + // so the ObjectIdleTime result should be <=now-start+1s + // link: https://github.com/redis/redis/blob/5b48d900498c85bbf4772c1d466c214439888115/src/object.c#L1265-L1272 Expect(idleTime.Val()).To(BeNumerically("<=", time.Now().Sub(start)+time.Second)) }) @@ -1645,6 +1645,32 @@ var _ = Describe("Commands", func() { Expect(strLen.Err()).NotTo(HaveOccurred()) Expect(strLen.Val()).To(Equal(int64(0))) }) + + It("should Copy", func() { + set := client.Set(ctx, "key", "hello", 0) + Expect(set.Err()).NotTo(HaveOccurred()) + Expect(set.Val()).To(Equal("OK")) + + copy := client.Copy(ctx, "key", "newKey", redisOptions().DB, false) + Expect(copy.Err()).NotTo(HaveOccurred()) + Expect(copy.Val()).To(Equal(int64(1))) + + // Value is available by both keys now + getOld := client.Get(ctx, "key") + Expect(getOld.Err()).NotTo(HaveOccurred()) + Expect(getOld.Val()).To(Equal("hello")) + getNew := client.Get(ctx, "newKey") + Expect(getNew.Err()).NotTo(HaveOccurred()) + Expect(getNew.Val()).To(Equal("hello")) + + // Overwriting an existing key should not succeed + overwrite := client.Copy(ctx, "newKey", "key", redisOptions().DB, false) + Expect(overwrite.Val()).To(Equal(int64(0))) + + // Overwrite is allowed when replace=rue + replace := client.Copy(ctx, "newKey", "key", redisOptions().DB, true) + Expect(replace.Val()).To(Equal(int64(1))) + }) }) Describe("hashes", func() { @@ -2386,6 +2412,28 @@ var _ = Describe("Commands", func() { Expect(lRange.Err()).NotTo(HaveOccurred()) Expect(lRange.Val()).To(Equal([]string{"san"})) }) + + It("should BLMove", func() { + rPush := client.RPush(ctx, "blmove1", "ichi") + Expect(rPush.Err()).NotTo(HaveOccurred()) + Expect(rPush.Val()).To(Equal(int64(1))) + + rPush = client.RPush(ctx, "blmove1", "ni") + Expect(rPush.Err()).NotTo(HaveOccurred()) + Expect(rPush.Val()).To(Equal(int64(2))) + + rPush = client.RPush(ctx, "blmove1", "san") + Expect(rPush.Err()).NotTo(HaveOccurred()) + Expect(rPush.Val()).To(Equal(int64(3))) + + blMove := client.BLMove(ctx, "blmove1", "blmove2", "RIGHT", "LEFT", time.Second) + Expect(blMove.Err()).NotTo(HaveOccurred()) + Expect(blMove.Val()).To(Equal("san")) + + lRange := client.LRange(ctx, "blmove2", 0, -1) + Expect(lRange.Err()).NotTo(HaveOccurred()) + Expect(lRange.Val()).To(Equal([]string{"san"})) + }) }) Describe("sets", func() { diff --git a/error.go b/error.go index ad9e173ea7..521594bbd0 100644 --- a/error.go +++ b/error.go @@ -65,7 +65,7 @@ func isRedisError(err error) bool { return ok } -func isBadConn(err error, allowTimeout bool) bool { +func isBadConn(err error, allowTimeout bool, addr string) bool { switch err { case nil: return false @@ -74,9 +74,19 @@ func isBadConn(err error, allowTimeout bool) bool { } if isRedisError(err) { - // Close connections in read only state in case domain addr is used - // and domain resolves to a different Redis Server. See #790. - return isReadOnlyError(err) + switch { + case isReadOnlyError(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): + // 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: + return false + } } if allowTimeout { @@ -119,6 +129,14 @@ func isReadOnlyError(err error) bool { return strings.HasPrefix(err.Error(), "READONLY ") } +func isMovedSameConnAddr(err error, addr string) bool { + redisError := err.Error() + if !strings.HasPrefix(redisError, "MOVED ") { + return false + } + return strings.HasSuffix(redisError, " "+addr) +} + //------------------------------------------------------------------------------ type timeoutError interface { diff --git a/example/del-keys-without-ttl/README.md b/example/del-keys-without-ttl/README.md new file mode 100644 index 0000000000..c112ee25d5 --- /dev/null +++ b/example/del-keys-without-ttl/README.md @@ -0,0 +1,11 @@ +# Delete keys without a ttl + +This example demonstrates how to use `SCAN` and pipelines to efficiently delete keys without a TTL. + +To run this example: + +```shell +go run . +``` + +See [documentation](https://redis.uptrace.dev/guide/get-all-keys.html) for more details. diff --git a/example/del-keys-without-ttl/go.mod b/example/del-keys-without-ttl/go.mod new file mode 100644 index 0000000000..4421e29f25 --- /dev/null +++ b/example/del-keys-without-ttl/go.mod @@ -0,0 +1,7 @@ +module github.com/go-redis/redis/example/del-keys-without-ttl + +go 1.14 + +replace github.com/go-redis/redis/v8 => ../.. + +require github.com/go-redis/redis/v8 v8.11.5 diff --git a/extra/redisotel/example/go.sum b/example/del-keys-without-ttl/go.sum similarity index 56% rename from extra/redisotel/example/go.sum rename to example/del-keys-without-ttl/go.sum index 4e05e032a0..142b2afe28 100644 --- a/extra/redisotel/example/go.sum +++ b/example/del-keys-without-ttl/go.sum @@ -1,20 +1,16 @@ -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-redis/redis/extra/rediscmd/v8 v8.8.2 h1:kjH+FAEz3G8gq8zDBgoLSCZj19Z1SK4dg/VtD3QE1IE= -github.com/go-redis/redis/extra/rediscmd/v8 v8.8.2/go.mod h1:1BL5EW0eGp6pj3Id4HYKCH0QTJWZZNKhWjYIGzKASqY= -github.com/go-redis/redis/extra/redisotel/v8 v8.8.2 h1:bJEPlEwcXNJkF7DF6m9thpyvU95PBqjDY+U80TIWfsY= -github.com/go-redis/redis/extra/redisotel/v8 v8.8.2/go.mod h1:zNGA0eMppmrbs2+VUMRx32FCb+nrB5yEGtYp1wKqeC8= -github.com/go-redis/redis/v8 v8.4.4/go.mod h1:nA0bQuF0i5JFx4Ta9RZxGKXFrQ8cRWntra97f0196iY= -github.com/go-redis/redis/v8 v8.8.2 h1:O/NcHqobw7SEptA0yA6up6spZVFtwE06SXM8rgLtsP8= -github.com/go-redis/redis/v8 v8.8.2/go.mod h1:F7resOH5Kdug49Otu24RjHWwgK7u9AmtqWMnCV1iP5Y= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -22,56 +18,36 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= -github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ= -github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= -github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v0.15.0/go.mod h1:e4GKElweB8W2gWUqbghw0B8t5MCTccc9212eNHnOHwA= -go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg= -go.opentelemetry.io/otel v1.0.0-RC1 h1:4CeoX93DNTWt8awGK9JmNXzF9j7TyOu9upscEdtcdXc= -go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.0-RC1 h1:SEfJImgKQ5TP2aTJwN08qhS8oFlYWr/neECGsyuxKWg= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.0-RC1/go.mod h1:TAM/UYjVd1UdaifWkof3qj9cCW9oINemHfj0K6yodSo= -go.opentelemetry.io/otel/internal/metric v0.21.0 h1:gZlIBo5O51hZOOZz8vEcuRx/l5dnADadKfpT70AELoo= -go.opentelemetry.io/otel/internal/metric v0.21.0/go.mod h1:iOfAaY2YycsXfYD4kaRSbLx2LKmfpKObWBEv9QK5zFo= -go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc= -go.opentelemetry.io/otel/metric v0.21.0 h1:ZtcJlHqVE4l8Su0WOLOd9fEPheJuYEiQ0wr9wv2p25I= -go.opentelemetry.io/otel/metric v0.21.0/go.mod h1:JWCt1bjivC4iCrz/aCrM1GSw+ZcvY44KCbaeeRhzHnc= -go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA= -go.opentelemetry.io/otel/oteltest v1.0.0-RC1 h1:G685iP3XiskCwk/z0eIabL55XUl2gk0cljhGk9sB0Yk= -go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4= -go.opentelemetry.io/otel/sdk v1.0.0-RC1 h1:Sy2VLOOg24bipyC29PhuMXYNJrLsxkie8hyI7kUlG9Q= -go.opentelemetry.io/otel/sdk v1.0.0-RC1/go.mod h1:kj6yPn7Pgt5ByRuwesbaWcRLA+V7BSDg3Hf8xRvsvf8= -go.opentelemetry.io/otel/sdk/export/metric v0.21.0 h1:4tSMVkDbvrowOeP/6rOfGABEWv5n+0gCfhI/TWleUvc= -go.opentelemetry.io/otel/sdk/export/metric v0.21.0/go.mod h1:gTaOMSQmL4zfsTL47desIPbPla5MyMG29lN3PzcibVg= -go.opentelemetry.io/otel/sdk/metric v0.21.0 h1:LNLUj35NNdEpyJQwj/htiEsfnY6GeTIwYHweCJNV+nc= -go.opentelemetry.io/otel/sdk/metric v0.21.0/go.mod h1:OHOcF8ZjE/L8oL/QXpUFWklPwtaukrfHgoAiPek53rQ= -go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg= -go.opentelemetry.io/otel/trace v1.0.0-RC1 h1:jrjqKJZEibFrDz+umEASeU3LvdVyWKlnTh7XEfwrT58= -go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -81,8 +57,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -92,21 +68,26 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -114,12 +95,16 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/example/del-keys-without-ttl/main.go b/example/del-keys-without-ttl/main.go new file mode 100644 index 0000000000..2331ed1027 --- /dev/null +++ b/example/del-keys-without-ttl/main.go @@ -0,0 +1,142 @@ +package main + +import ( + "context" + "fmt" + "sync" + + "github.com/go-redis/redis/v8" +) + +func main() { + ctx := context.Background() + + rdb := redis.NewClient(&redis.Options{ + Addr: ":6379", + }) + + ch := make(chan string, 100) + var wg sync.WaitGroup + + wg.Add(1) + go func() { + defer wg.Done() + deleted, err := process(ctx, rdb, ch) + if err != nil { + panic(err) + } + fmt.Println("deleted", deleted, "keys") + }() + + iter := rdb.Scan(ctx, 0, "", 0).Iterator() + for iter.Next(ctx) { + ch <- iter.Val() + } + if err := iter.Err(); err != nil { + panic(err) + } + + close(ch) + wg.Wait() +} + +func process(ctx context.Context, rdb *redis.Client, in <-chan string) (int, error) { + var wg sync.WaitGroup + + out := make(chan string, 100) + defer func() { + close(out) + wg.Wait() + }() + + wg.Add(1) + go func() { + defer wg.Done() + if err := del(ctx, rdb, out); err != nil { + panic(err) + } + }() + + var deleted int + + keys := make([]string, 0, 100) + for key := range in { + keys = append(keys, key) + if len(keys) < 100 { + continue + } + + var err error + keys, err = checkTTL(ctx, rdb, keys) + if err != nil { + return 0, err + } + + for _, key := range keys { + out <- key + } + deleted += len(keys) + + keys = keys[:0] + } + + if len(keys) > 0 { + keys, err := checkTTL(ctx, rdb, keys) + if err != nil { + return 0, err + } + + for _, key := range keys { + out <- key + } + deleted += len(keys) + } + + return deleted, nil +} + +func checkTTL(ctx context.Context, rdb *redis.Client, keys []string) ([]string, error) { + cmds, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error { + for _, key := range keys { + pipe.TTL(ctx, key) + } + return nil + }) + if err != nil { + return nil, err + } + + for i := len(cmds) - 1; i >= 0; i-- { + d, err := cmds[i].(*redis.DurationCmd).Result() + if err != nil { + return nil, err + } + if d != -1 { + keys = append(keys[:i], keys[i+1:]...) + } + } + + return keys, nil +} + +func del(ctx context.Context, rdb *redis.Client, in <-chan string) error { + pipe := rdb.Pipeline() + + for key := range in { + pipe.Del(ctx, key) + + if pipe.Len() < 100 { + continue + } + + if _, err := pipe.Exec(ctx); err != nil { + return err + } + } + + if _, err := pipe.Exec(ctx); err != nil { + return err + } + + return nil +} diff --git a/example/hll/README.md b/example/hll/README.md new file mode 100644 index 0000000000..cd78d7f1e0 --- /dev/null +++ b/example/hll/README.md @@ -0,0 +1,9 @@ +# Redis HyperLogLog example + +To run this example: + +```shell +go run . +``` + +See [Using HyperLogLog command with go-redis](https://redis.uptrace.dev/guide/hll.html) for details. diff --git a/example/hll/go.mod b/example/hll/go.mod new file mode 100644 index 0000000000..33d76306d5 --- /dev/null +++ b/example/hll/go.mod @@ -0,0 +1,7 @@ +module github.com/go-redis/redis/example/hll + +go 1.14 + +replace github.com/go-redis/redis/v8 => ../.. + +require github.com/go-redis/redis/v8 v8.11.5 diff --git a/example/hll/go.sum b/example/hll/go.sum new file mode 100644 index 0000000000..142b2afe28 --- /dev/null +++ b/example/hll/go.sum @@ -0,0 +1,110 @@ +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/example/hll/main.go b/example/hll/main.go new file mode 100644 index 0000000000..60a957e9ca --- /dev/null +++ b/example/hll/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "context" + "fmt" + + "github.com/go-redis/redis/v8" +) + +func main() { + ctx := context.Background() + + rdb := redis.NewClient(&redis.Options{ + Addr: ":6379", + }) + _ = rdb.FlushDB(ctx).Err() + + for i := 0; i < 10; i++ { + if err := rdb.PFAdd(ctx, "myset", fmt.Sprint(i)).Err(); err != nil { + panic(err) + } + } + + card, err := rdb.PFCount(ctx, "myset").Result() + if err != nil { + panic(err) + } + + fmt.Println("set cardinality", card) +} diff --git a/example/lua-scripting/README.md b/example/lua-scripting/README.md new file mode 100644 index 0000000000..3272d7d30b --- /dev/null +++ b/example/lua-scripting/README.md @@ -0,0 +1,8 @@ +# Redis Lua scripting example + +This is an example for [Redis Lua scripting](https://redis.uptrace.dev/guide/lua-scripting.html) +article. To run it: + +```shell +go run . +``` diff --git a/example/lua-scripting/go.mod b/example/lua-scripting/go.mod new file mode 100644 index 0000000000..be4ecab23e --- /dev/null +++ b/example/lua-scripting/go.mod @@ -0,0 +1,7 @@ +module github.com/go-redis/redis/example/redis-bloom + +go 1.14 + +replace github.com/go-redis/redis/v8 => ../.. + +require github.com/go-redis/redis/v8 v8.11.5 diff --git a/example/lua-scripting/go.sum b/example/lua-scripting/go.sum new file mode 100644 index 0000000000..142b2afe28 --- /dev/null +++ b/example/lua-scripting/go.sum @@ -0,0 +1,110 @@ +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/example/lua-scripting/main.go b/example/lua-scripting/main.go new file mode 100644 index 0000000000..04cb44d939 --- /dev/null +++ b/example/lua-scripting/main.go @@ -0,0 +1,66 @@ +package main + +import ( + "context" + "fmt" + + "github.com/go-redis/redis/v8" +) + +func main() { + ctx := context.Background() + + rdb := redis.NewClient(&redis.Options{ + Addr: ":6379", + }) + _ = rdb.FlushDB(ctx).Err() + + fmt.Printf("# INCR BY\n") + for _, change := range []int{+1, +5, 0} { + num, err := incrBy.Run(ctx, rdb, []string{"my_counter"}, change).Int() + if err != nil { + panic(err) + } + fmt.Printf("incr by %d: %d\n", change, num) + } + + fmt.Printf("\n# SUM\n") + sum, err := sum.Run(ctx, rdb, []string{"my_sum"}, 1, 2, 3).Int() + if err != nil { + panic(err) + } + fmt.Printf("sum is: %d\n", sum) +} + +var incrBy = redis.NewScript(` +local key = KEYS[1] +local change = ARGV[1] + +local value = redis.call("GET", key) +if not value then + value = 0 +end + +value = value + change +redis.call("SET", key, value) + +return value +`) + +var sum = redis.NewScript(` +local key = KEYS[1] + +local sum = redis.call("GET", key) +if not sum then + sum = 0 +end + +local num_arg = #ARGV +for i = 1, num_arg do + sum = sum + ARGV[i] +end + +redis.call("SET", key, sum) + +return sum +`) diff --git a/example/otel/README.md b/example/otel/README.md index 60d4d121d6..567a882779 100644 --- a/example/otel/README.md +++ b/example/otel/README.md @@ -1,9 +1,34 @@ -### OpenTelemetry Example -Prints spans and metrics to the console. -#### To Run: -- `docker-compose up -d` -- `go run .` +# Example for go-redis OpenTelemetry instrumentation -When you're finished, be sure to run `docker-compose down` to shutdown -the redis server. +See [Monitoring performance and errors](https://redis.uptrace.dev/guide/tracing.html) for details. +This example requires Redis Server on port `:6379`. You can start Redis Server using Docker: + +```shell +docker-compose up -d +``` + +You can run this example with different OpenTelemetry exporters by providing environment variables. + +**Stdout** exporter (default): + +```shell +go run . +``` + +**Jaeger** exporter: + +```shell +OTEL_EXPORTER_JAEGER_ENDPOINT=http://localhost:14268/api/traces go run . +``` + +**Uptrace** exporter: + +```shell +UPTRACE_DSN="https://@uptrace.dev/" go run . +``` + +## Links + +- [Find instrumentations](https://opentelemetry.uptrace.dev/instrumentations/?lang=go) +- [OpenTelemetry Tracing API](https://opentelemetry.uptrace.dev/guide/go-tracing.html) diff --git a/example/otel/docker-compose.yml b/example/otel/docker-compose.yml index c2d7f1d41c..ff8f0669ac 100644 --- a/example/otel/docker-compose.yml +++ b/example/otel/docker-compose.yml @@ -1,8 +1,9 @@ version: '3' + services: redis-server: image: redis ports: - - "6379:6379" + - '6379:6379' redis-cli: image: redis diff --git a/example/otel/example-client.go b/example/otel/example-client.go deleted file mode 100644 index 2eb8d50b5d..0000000000 --- a/example/otel/example-client.go +++ /dev/null @@ -1,85 +0,0 @@ -package main - -import ( - "context" - "log" - "sync" - "time" - - "github.com/go-redis/redis/v8" - "github.com/go-redis/redis/v8/extra/redisotel" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/exporters/stdout" - controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" - processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" - "go.opentelemetry.io/otel/sdk/metric/selector/simple" - sdktrace "go.opentelemetry.io/otel/sdk/trace" -) - -func main() { - ctx := context.Background() - - stop := runExporter(ctx) - defer stop(ctx) - - rdb := redis.NewClient(&redis.Options{ - Addr: ":6379", - }) - - rdb.AddHook(redisotel.TracingHook{}) - - tracer := otel.Tracer("Example tracer") - ctx, span := tracer.Start(ctx, "start-test-span") - - rdb.Set(ctx, "First value", "value_1", 0) - - rdb.Set(ctx, "Second value", "value_2", 0) - - var group sync.WaitGroup - - for i := 0; i < 20; i++ { - group.Add(1) - go func() { - defer group.Done() - val := rdb.Get(ctx, "Second value").Val() - if val != "value_2" { - log.Fatalf("val was not set. expected: %s but got: %s", "value_2", val) - } - }() - } - group.Wait() - - rdb.Del(ctx, "First value") - rdb.Del(ctx, "Second value") - - // Wait some time to allow spans to export - <-time.After(5 * time.Second) - span.End() -} - -func runExporter(ctx context.Context) func(context.Context) error { - exporter, err := stdout.NewExporter(stdout.WithPrettyPrint()) - if err != nil { - log.Fatal(err) - } - - tp := sdktrace.NewTracerProvider( - sdktrace.WithSyncer(exporter), - sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), - ) - otel.SetTracerProvider(tp) - - ctrl := controller.New( - processor.New( - simple.NewWithExactDistribution(), - exporter, - ), - controller.WithPusher(exporter), - controller.WithCollectPeriod(1*time.Second), - ) - if err := ctrl.Start(ctx); err != nil { - log.Fatal(err) - } - - return ctrl.Stop -} diff --git a/example/otel/go.mod b/example/otel/go.mod index a9f26ff8eb..afe12ab8d4 100644 --- a/example/otel/go.mod +++ b/example/otel/go.mod @@ -2,14 +2,19 @@ module github.com/go-redis/redis/example/otel go 1.14 -require ( - github.com/go-redis/redis/v8 v8.4.4 - github.com/go-redis/redis/v8/extra/redisotel v0.0.0-00010101000000-000000000000 - go.opentelemetry.io/otel v0.16.0 - go.opentelemetry.io/otel/exporters/stdout v0.16.0 - go.opentelemetry.io/otel/sdk v0.16.0 -) +replace github.com/go-redis/redis/v8 => ../.. + +replace github.com/go-redis/redis/extra/redisotel/v8 => ../../extra/redisotel -replace github.com/go-redis/redis/v8 => ../../ +replace github.com/go-redis/redis/extra/rediscmd/v8 => ../../extra/rediscmd -replace github.com/go-redis/redis/v8/extra/redisotel => ../../extra/redisotel +require ( + github.com/go-redis/redis/extra/redisotel/v8 v8.11.5 + github.com/go-redis/redis/v8 v8.11.5 + github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.10 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/exporters/jaeger v1.5.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.5.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.5.0 // indirect + golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf // indirect +) diff --git a/example/otel/go.sum b/example/otel/go.sum index 0a833c9f97..4c41bc4036 100644 --- a/example/otel/go.sum +++ b/example/otel/go.sum @@ -1,106 +1,291 @@ -github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg= -github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= +github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-redis/redis/extra/rediscmd v0.2.0 h1:A3bhCsCKsedClEH9/jYlcKqOuBoeeV+H0yDie5t+a6w= -github.com/go-redis/redis/extra/rediscmd v0.2.0/go.mod h1:Z5bP1EHl9PvWhx/DupfCdZwB0JgOO3aVxWc/PFux+BE= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= -github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= -github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.10 h1:STSRpcp18xb6huePD0yj4uiUFd1cOdb2xexhhPNWwCo= +github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.10/go.mod h1:7UDvwITVMKhXZGmxKa/lJujNIOKb5ReIRAVwwrc60bI= +github.com/uptrace/uptrace-go v1.4.0 h1:WPYpiCi84nSAXVdtZQamcmDnTZz9724EONo8v1ud9/0= +github.com/uptrace/uptrace-go v1.4.0/go.mod h1:KAPqyJuSaRA6YOea6UZEuSeXtWap92Qws9rPYNW8GhU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v0.16.0 h1:uIWEbdeb4vpKPGITLsRVUS44L5oDbDUCZxn8lkxhmgw= -go.opentelemetry.io/otel v0.16.0/go.mod h1:e4GKElweB8W2gWUqbghw0B8t5MCTccc9212eNHnOHwA= -go.opentelemetry.io/otel/exporters/stdout v0.16.0 h1:lQG6ZZYLh3NxnmrHltRmqZolT/jPJ8Qfl74lWT8g69Y= -go.opentelemetry.io/otel/exporters/stdout v0.16.0/go.mod h1:bq7m22M7WIxz30KnxH9lI4RLKPajk0lnLsd5P2MsSv8= -go.opentelemetry.io/otel/sdk v0.16.0 h1:5o+fkNsOfH5Mix1bHUApNBqeDcAYczHDa7Ix+R73K2U= -go.opentelemetry.io/otel/sdk v0.16.0/go.mod h1:Jb0B4wrxerxtBeapvstmAZvJGQmvah4dHgKSngDpiCo= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opentelemetry.io/contrib/instrumentation/runtime v0.27.0/go.mod h1:6ZYYPfSKyhnkpw3xOssb1PMclnNs8dnSzO5POa+02ys= +go.opentelemetry.io/contrib/instrumentation/runtime v0.29.0 h1:ZnLxB76QjHDLnrUWLYgcCc8lcdRGoraTLvJEWmwwC80= +go.opentelemetry.io/contrib/instrumentation/runtime v0.29.0/go.mod h1:qGVpMUNpULYYXRYCQB3DNUe+of22Y+M28i1Oke8SuKQ= +go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I= +go.opentelemetry.io/otel v1.4.0/go.mod h1:jeAqMFKy2uLIxCtKxoFj0FAL5zAPKQagc3+GtBWakzk= +go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4= +go.opentelemetry.io/otel v1.5.0 h1:DhCU8oR2sJH9rfnwPdoV/+BJ7UIN5kXHL8DuSGrPU8E= +go.opentelemetry.io/otel v1.5.0/go.mod h1:Jm/m+rNp/z0eqJc74H7LPwQ3G87qkU/AnnAydAjSAHk= +go.opentelemetry.io/otel/exporters/jaeger v1.4.1/go.mod h1:ZW7vkOu9nC1CxsD8bHNHCia5JUbwP39vxgd1q4Z5rCI= +go.opentelemetry.io/otel/exporters/jaeger v1.5.0 h1:ZR7nhLSfLufS5AHk/iN11Q+W9XYwsJrVZ1Frb833d+Y= +go.opentelemetry.io/otel/exporters/jaeger v1.5.0/go.mod h1:rSeUArMBRe1eQLo1T0WxOazohN1M2mYThWJQmn1BjRQ= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 h1:lC0ldaVQwBpO1G5IaOYRbBCa67h6ioGkK6qYkqZbYOI= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.27.0 h1:t1aPfMj5oZzv2EaRmdC2QPQg1a7MaBjraOh4Hjwuia8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.27.0/go.mod h1:aZnoYVx7GIuMROciGC3cjZhYxMD/lKroRJUnFY0afu0= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.27.0 h1:RJURCSrqUjJiCY3GuFCVP2EPKOQLwNXQ4FI3aH2KoHg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.27.0/go.mod h1:LIc1eCpkU94tPnXxH40ya41Oyxm7sL+oDvxCYPFpnV8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.0/go.mod h1:3oS+j2WUoJVyj6/BzQN/52G17lNJDulngsOxDm1w2PY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1/go.mod h1:o5RW5o2pKpJLD5dNTCmjF1DorYwMeFJmb/rKr5sLaa8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.5.0 h1:Arn+HOtC6neocvr6J4ykfILvtiSwoDkkLFMaVLFKBnY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.5.0/go.mod h1:VoN81wyy6jVVCzHImh8S+IYhw+oAUj6XgEsTkP8DyrQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.0/go.mod h1:ew1NcwkHo0QFT3uTm3m2IVZMkZdVIpbOYNPasgWwpdk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1/go.mod h1:c6E4V3/U+miqjs/8l950wggHGL1qzlp0Ypj9xoGrPqo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.5.0 h1:dOXExSS490NJaVZD496oIK2Z22S1JQnOsrrMh/p/mLU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.5.0/go.mod h1:Es/Ag4ORtjwWCRjS0aEXgmxB5VqKQlnp481/P5aZyPQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.0/go.mod h1:TqC+Li5O2V5hRWq4TkIx0oHFu/McCi/KAVGBaKkhU5Q= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.1/go.mod h1:BFiGsTMZdqtxufux8ANXuMeRz9dMPVFdJZadUWDFD7o= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.5.0 h1:/Lu2JuL9Mb+B+kSv/RsDMgA/5FaBaxfyfMnICFepiBs= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.5.0/go.mod h1:5gUXICq93HyDh8Rij7p8ilJEC1Sqk0u3lSGs62i8hJQ= +go.opentelemetry.io/otel/internal/metric v0.25.0/go.mod h1:Nhuw26QSX7d6n4duoqAFi5KOQR4AuzyMcl5eXOgwxtc= +go.opentelemetry.io/otel/internal/metric v0.27.0 h1:9dAVGAfFiiEq5NVB9FUJ5et+btbDQAUIJehJ+ikyryk= +go.opentelemetry.io/otel/internal/metric v0.27.0/go.mod h1:n1CVxRqKqYZtqyTh9U/onvKapPGv7y/rpyOTI+LFNzw= +go.opentelemetry.io/otel/metric v0.25.0/go.mod h1:E884FSpQfnJOMMUaq+05IWlJ4rjZpk2s/F1Ju+TEEm8= +go.opentelemetry.io/otel/metric v0.27.0 h1:HhJPsGhJoKRSegPQILFbODU56NS/L1UE4fS1sC5kIwQ= +go.opentelemetry.io/otel/metric v0.27.0/go.mod h1:raXDJ7uP2/Jc0nVZWQjJtzoyssOYWu/+pjZqRzfvZ7g= +go.opentelemetry.io/otel/sdk v1.4.0/go.mod h1:71GJPNJh4Qju6zJuYl1CrYtXbrgfau/M9UAggqiy1UE= +go.opentelemetry.io/otel/sdk v1.4.1/go.mod h1:NBwHDgDIBYjwK2WNu1OPgsIc2IJzmBXNnvIJxJc8BpE= +go.opentelemetry.io/otel/sdk v1.5.0 h1:QKhWBbcOC9fDCZKCfPFjWTWpfIlJR+i9xiUDYrLVmZs= +go.opentelemetry.io/otel/sdk v1.5.0/go.mod h1:CU4J1v+7iEljnm1G14QjdFWOXUyYLHVh0Lh+/BTYyFg= +go.opentelemetry.io/otel/sdk/metric v0.27.0 h1:CDEu96Js5IP7f4bJ8eimxF09V5hKYmE7CeyKSjmAL1s= +go.opentelemetry.io/otel/sdk/metric v0.27.0/go.mod h1:lOgrT5C3ORdbqp2LsDrx+pBj6gbZtQ5Omk27vH3EaW0= +go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0= +go.opentelemetry.io/otel/trace v1.4.0/go.mod h1:uc3eRsqDfWs9R7b92xbQbU42/eTNz4N+gLP8qJCi4aE= +go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc= +go.opentelemetry.io/otel/trace v1.5.0 h1:AKQZ9zJsBRFAp7zLdyGNkqG2rToCDIt3i5tcLzQlbmU= +go.opentelemetry.io/otel/trace v1.5.0/go.mod h1:sq55kfhjXYr1zVSyexg0w1mpa03AYXR5eyTkB9NPPdE= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= +go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf h1:Fm4IcnUL803i92qDlmB0obyHmosDrxZWxJL3gIeNqOw= +golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106 h1:ErU+UA6wxadoU8nWrsy5MZUVBs75K17zUCsUCIfrXCE= +google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/example/otel/main.go b/example/otel/main.go new file mode 100644 index 0000000000..952b24b74f --- /dev/null +++ b/example/otel/main.go @@ -0,0 +1,72 @@ +package main + +import ( + "context" + "log" + "sync" + + "github.com/uptrace/opentelemetry-go-extra/otelplay" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/codes" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + + "github.com/go-redis/redis/extra/redisotel/v8" + "github.com/go-redis/redis/v8" +) + +var tracer = otel.Tracer("redisexample") + +func main() { + ctx := context.Background() + + shutdown := otelplay.ConfigureOpentelemetry(ctx) + defer shutdown() + + rdb := redis.NewClient(&redis.Options{ + Addr: ":6379", + }) + rdb.AddHook(redisotel.NewTracingHook(redisotel.WithAttributes(semconv.NetPeerNameKey.String("localhost"), semconv.NetPeerPortKey.String("6379")))) + + ctx, span := tracer.Start(ctx, "handleRequest") + defer span.End() + + if err := handleRequest(ctx, rdb); err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) + } + + otelplay.PrintTraceID(ctx) +} + +func handleRequest(ctx context.Context, rdb *redis.Client) error { + if err := rdb.Set(ctx, "First value", "value_1", 0).Err(); err != nil { + return err + } + if err := rdb.Set(ctx, "Second value", "value_2", 0).Err(); err != nil { + return err + } + + var group sync.WaitGroup + + for i := 0; i < 20; i++ { + group.Add(1) + go func() { + defer group.Done() + val := rdb.Get(ctx, "Second value").Val() + if val != "value_2" { + log.Printf("%q != %q", val, "value_2") + } + }() + } + + group.Wait() + + if err := rdb.Del(ctx, "First value").Err(); err != nil { + return err + } + if err := rdb.Del(ctx, "Second value").Err(); err != nil { + return err + } + + return nil +} diff --git a/example/redis-bloom/README.md b/example/redis-bloom/README.md new file mode 100644 index 0000000000..e2a7542a63 --- /dev/null +++ b/example/redis-bloom/README.md @@ -0,0 +1,12 @@ +# RedisBloom example for go-redis + +This is an example for +[Bloom, Cuckoo, Count-Min, Top-K](https://redis.uptrace.dev/guide/bloom-cuckoo-count-min-top-k.html) +article. + +To run it, you need to compile and install +[RedisBloom](https://oss.redis.com/redisbloom/Quick_Start/#building) module: + +```shell +go run . +``` diff --git a/example/redis-bloom/go.mod b/example/redis-bloom/go.mod new file mode 100644 index 0000000000..be4ecab23e --- /dev/null +++ b/example/redis-bloom/go.mod @@ -0,0 +1,7 @@ +module github.com/go-redis/redis/example/redis-bloom + +go 1.14 + +replace github.com/go-redis/redis/v8 => ../.. + +require github.com/go-redis/redis/v8 v8.11.5 diff --git a/example/redis-bloom/go.sum b/example/redis-bloom/go.sum new file mode 100644 index 0000000000..142b2afe28 --- /dev/null +++ b/example/redis-bloom/go.sum @@ -0,0 +1,110 @@ +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/example/redis-bloom/main.go b/example/redis-bloom/main.go new file mode 100644 index 0000000000..c2ae7c08ad --- /dev/null +++ b/example/redis-bloom/main.go @@ -0,0 +1,155 @@ +package main + +import ( + "context" + "fmt" + "math/rand" + + "github.com/go-redis/redis/v8" +) + +func main() { + ctx := context.Background() + + rdb := redis.NewClient(&redis.Options{ + Addr: ":6379", + }) + _ = rdb.FlushDB(ctx).Err() + + fmt.Printf("# BLOOM\n") + bloomFilter(ctx, rdb) + + fmt.Printf("\n# CUCKOO\n") + cuckooFilter(ctx, rdb) + + fmt.Printf("\n# COUNT-MIN\n") + countMinSketch(ctx, rdb) + + fmt.Printf("\n# TOP-K\n") + topK(ctx, rdb) +} + +func bloomFilter(ctx context.Context, rdb *redis.Client) { + inserted, err := rdb.Do(ctx, "BF.ADD", "bf_key", "item0").Bool() + if err != nil { + panic(err) + } + if inserted { + fmt.Println("item0 was inserted") + } else { + fmt.Println("item0 already exists") + } + + for _, item := range []string{"item0", "item1"} { + exists, err := rdb.Do(ctx, "BF.EXISTS", "bf_key", item).Bool() + if err != nil { + panic(err) + } + if exists { + fmt.Printf("%s does exist\n", item) + } else { + fmt.Printf("%s does not exist\n", item) + } + } + + bools, err := rdb.Do(ctx, "BF.MADD", "bf_key", "item1", "item2", "item3").BoolSlice() + if err != nil { + panic(err) + } + fmt.Println("adding multiple items:", bools) +} + +func cuckooFilter(ctx context.Context, rdb *redis.Client) { + inserted, err := rdb.Do(ctx, "CF.ADDNX", "cf_key", "item0").Bool() + if err != nil { + panic(err) + } + if inserted { + fmt.Println("item0 was inserted") + } else { + fmt.Println("item0 already exists") + } + + for _, item := range []string{"item0", "item1"} { + exists, err := rdb.Do(ctx, "CF.EXISTS", "cf_key", item).Bool() + if err != nil { + panic(err) + } + if exists { + fmt.Printf("%s does exist\n", item) + } else { + fmt.Printf("%s does not exist\n", item) + } + } + + deleted, err := rdb.Do(ctx, "CF.DEL", "cf_key", "item0").Bool() + if err != nil { + panic(err) + } + if deleted { + fmt.Println("item0 was deleted") + } +} + +func countMinSketch(ctx context.Context, rdb *redis.Client) { + if err := rdb.Do(ctx, "CMS.INITBYPROB", "count_min", 0.001, 0.01).Err(); err != nil { + panic(err) + } + + items := []string{"item1", "item2", "item3", "item4", "item5"} + counts := make(map[string]int, len(items)) + + for i := 0; i < 10000; i++ { + n := rand.Intn(len(items)) + item := items[n] + + if err := rdb.Do(ctx, "CMS.INCRBY", "count_min", item, 1).Err(); err != nil { + panic(err) + } + counts[item]++ + } + + for item, count := range counts { + ns, err := rdb.Do(ctx, "CMS.QUERY", "count_min", item).Int64Slice() + if err != nil { + panic(err) + } + fmt.Printf("%s: count-min=%d actual=%d\n", item, ns[0], count) + } +} + +func topK(ctx context.Context, rdb *redis.Client) { + if err := rdb.Do(ctx, "TOPK.RESERVE", "top_items", 3).Err(); err != nil { + panic(err) + } + + counts := map[string]int{ + "item1": 1000, + "item2": 2000, + "item3": 3000, + "item4": 4000, + "item5": 5000, + "item6": 6000, + } + + for item, count := range counts { + for i := 0; i < count; i++ { + if err := rdb.Do(ctx, "TOPK.INCRBY", "top_items", item, 1).Err(); err != nil { + panic(err) + } + } + } + + items, err := rdb.Do(ctx, "TOPK.LIST", "top_items").StringSlice() + if err != nil { + panic(err) + } + + for _, item := range items { + ns, err := rdb.Do(ctx, "TOPK.COUNT", "top_items", item).Int64Slice() + if err != nil { + panic(err) + } + fmt.Printf("%s: top-k=%d actual=%d\n", item, ns[0], counts[item]) + } +} diff --git a/example/scan-struct/README.md b/example/scan-struct/README.md new file mode 100644 index 0000000000..676f8e201a --- /dev/null +++ b/example/scan-struct/README.md @@ -0,0 +1,11 @@ +# Example for scanning hash fields into a struct + +To run this example: + +```shell +go run . +``` + +See +[Redis: Scanning hash fields into a struct](https://redis.uptrace.dev/guide/scanning-hash-fields.html) +for details. diff --git a/example/scan-struct/go.mod b/example/scan-struct/go.mod new file mode 100644 index 0000000000..8c42bef376 --- /dev/null +++ b/example/scan-struct/go.mod @@ -0,0 +1,10 @@ +module github.com/go-redis/redis/example/scan-struct + +go 1.14 + +replace github.com/go-redis/redis/v8 => ../.. + +require ( + github.com/davecgh/go-spew v1.1.1 + github.com/go-redis/redis/v8 v8.11.5 +) diff --git a/example/scan-struct/go.sum b/example/scan-struct/go.sum new file mode 100644 index 0000000000..f3be7f1926 --- /dev/null +++ b/example/scan-struct/go.sum @@ -0,0 +1,111 @@ +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/example/scan-struct/main.go b/example/scan-struct/main.go new file mode 100644 index 0000000000..aee7ef715e --- /dev/null +++ b/example/scan-struct/main.go @@ -0,0 +1,51 @@ +package main + +import ( + "context" + + "github.com/davecgh/go-spew/spew" + + "github.com/go-redis/redis/v8" +) + +type Model struct { + Str1 string `redis:"str1"` + Str2 string `redis:"str2"` + Int int `redis:"int"` + Bool bool `redis:"bool"` + Ignored struct{} `redis:"-"` +} + +func main() { + ctx := context.Background() + + rdb := redis.NewClient(&redis.Options{ + Addr: ":6379", + }) + + // Set some fields. + if _, err := rdb.Pipelined(ctx, func(rdb redis.Pipeliner) error { + rdb.HSet(ctx, "key", "str1", "hello") + rdb.HSet(ctx, "key", "str2", "world") + rdb.HSet(ctx, "key", "int", 123) + rdb.HSet(ctx, "key", "bool", 1) + return nil + }); err != nil { + panic(err) + } + + var model1, model2 Model + + // Scan all fields into the model. + if err := rdb.HGetAll(ctx, "key").Scan(&model1); err != nil { + panic(err) + } + + // Or scan a subset of the fields. + if err := rdb.HMGet(ctx, "key", "str1", "int").Scan(&model2); err != nil { + panic(err) + } + + spew.Dump(model1) + spew.Dump(model2) +} diff --git a/example_test.go b/example_test.go index 53bd90fe5d..75b5cbbb3a 100644 --- a/example_test.go +++ b/example_test.go @@ -39,13 +39,14 @@ func ExampleNewClient() { } func ExampleParseURL() { - opt, err := redis.ParseURL("redis://:qwerty@localhost:6379/1") + opt, err := redis.ParseURL("redis://:qwerty@localhost:6379/1?dial_timeout=5s") if err != nil { panic(err) } fmt.Println("addr is", opt.Addr) fmt.Println("db is", opt.DB) fmt.Println("password is", opt.Password) + fmt.Println("dial timeout is", opt.DialTimeout) // Create client as usually. _ = redis.NewClient(opt) @@ -53,6 +54,7 @@ func ExampleParseURL() { // Output: addr is localhost:6379 // db is 1 // password is qwerty + // dial timeout is 5s } func ExampleNewFailoverClient() { diff --git a/extra/rediscensus/go.mod b/extra/rediscensus/go.mod index a926b4ea53..8f82a0c805 100644 --- a/extra/rediscensus/go.mod +++ b/extra/rediscensus/go.mod @@ -2,10 +2,13 @@ module github.com/go-redis/redis/extra/rediscensus/v8 go 1.15 +replace github.com/go-redis/redis/v8 => ../.. + replace github.com/go-redis/redis/extra/rediscmd/v8 => ../rediscmd require ( - github.com/go-redis/redis/extra/rediscmd/v8 v8.8.2 - github.com/go-redis/redis/v8 v8.8.2 - go.opencensus.io v0.22.6 + github.com/go-redis/redis/extra/rediscmd/v8 v8.11.5 + github.com/go-redis/redis/v8 v8.11.5 + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + go.opencensus.io v0.23.0 ) diff --git a/extra/rediscensus/go.sum b/extra/rediscensus/go.sum index aaa94f45bc..5bfa139c56 100644 --- a/extra/rediscensus/go.sum +++ b/extra/rediscensus/go.sum @@ -1,12 +1,15 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -16,11 +19,11 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-redis/redis/v8 v8.4.4 h1:fGqgxCTR1sydaKI00oQf3OmkU/DIe/I/fYXvGklCIuc= -github.com/go-redis/redis/v8 v8.4.4/go.mod h1:nA0bQuF0i5JFx4Ta9RZxGKXFrQ8cRWntra97f0196iY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -31,41 +34,45 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= -github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ= -github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= -github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opencensus.io v0.22.6 h1:BdkrbWrzDlV9dnbzoP7sfN+dHheJ4J9JOaYxcUDL+ok= -go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/otel v0.15.0 h1:CZFy2lPhxd4HlhZnYK8gRyDotksO3Ip9rBweY1vVYJw= -go.opentelemetry.io/otel v0.15.0/go.mod h1:e4GKElweB8W2gWUqbghw0B8t5MCTccc9212eNHnOHwA= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -84,8 +91,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -98,15 +105,19 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -137,17 +148,20 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/extra/rediscensus/rediscensus.go b/extra/rediscensus/rediscensus.go index 1ea6a57cb8..9af094e944 100644 --- a/extra/rediscensus/rediscensus.go +++ b/extra/rediscensus/rediscensus.go @@ -3,9 +3,10 @@ package rediscensus import ( "context" + "go.opencensus.io/trace" + "github.com/go-redis/redis/extra/rediscmd/v8" "github.com/go-redis/redis/v8" - "go.opencensus.io/trace" ) type TracingHook struct{} diff --git a/extra/rediscmd/go.mod b/extra/rediscmd/go.mod index 8cc00e7c6e..1bc5bef4bf 100644 --- a/extra/rediscmd/go.mod +++ b/extra/rediscmd/go.mod @@ -2,8 +2,10 @@ module github.com/go-redis/redis/extra/rediscmd/v8 go 1.15 +replace github.com/go-redis/redis/v8 => ../.. + require ( - github.com/go-redis/redis/v8 v8.4.4 - github.com/onsi/ginkgo v1.15.0 - github.com/onsi/gomega v1.10.5 + github.com/go-redis/redis/v8 v8.11.5 + github.com/onsi/ginkgo v1.16.5 + github.com/onsi/gomega v1.18.1 ) diff --git a/extra/rediscmd/go.sum b/extra/rediscmd/go.sum index 964ee70e3a..142b2afe28 100644 --- a/extra/rediscmd/go.sum +++ b/extra/rediscmd/go.sum @@ -1,48 +1,53 @@ -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-redis/redis/v8 v8.4.4 h1:fGqgxCTR1sydaKI00oQf3OmkU/DIe/I/fYXvGklCIuc= -github.com/go-redis/redis/v8 v8.4.4/go.mod h1:nA0bQuF0i5JFx4Ta9RZxGKXFrQ8cRWntra97f0196iY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= -github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ= -github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= -github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v0.15.0 h1:CZFy2lPhxd4HlhZnYK8gRyDotksO3Ip9rBweY1vVYJw= -go.opentelemetry.io/otel v0.15.0/go.mod h1:e4GKElweB8W2gWUqbghw0B8t5MCTccc9212eNHnOHwA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -52,8 +57,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -63,15 +68,19 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -85,15 +94,17 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/extra/rediscmd/safe.go b/extra/rediscmd/safe.go index efe92f6e8d..6d3a8b7a29 100644 --- a/extra/rediscmd/safe.go +++ b/extra/rediscmd/safe.go @@ -1,3 +1,4 @@ +//go:build appengine // +build appengine package rediscmd diff --git a/extra/rediscmd/unsafe.go b/extra/rediscmd/unsafe.go index a90a48b713..7ccdf2fef2 100644 --- a/extra/rediscmd/unsafe.go +++ b/extra/rediscmd/unsafe.go @@ -1,3 +1,4 @@ +//go:build !appengine // +build !appengine package rediscmd diff --git a/extra/redisotel/example/Makefile b/extra/redisotel/example/Makefile deleted file mode 100644 index b986e35721..0000000000 --- a/extra/redisotel/example/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -build: - docker-compose build -up: build - docker-compose up --detach redis-server -down: - docker-compose down -logs: - docker-compose logs redis-server diff --git a/extra/redisotel/example/README.md b/extra/redisotel/example/README.md deleted file mode 100644 index 59abcc352e..0000000000 --- a/extra/redisotel/example/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# OpenTelemetry instrumentation for go-redis - -To run this example you need a Redis server. You can start one with Docker: - -```shell -make up -``` - -Then run the example: - -```shell -go run main.go -``` diff --git a/extra/redisotel/example/docker-compose.yml b/extra/redisotel/example/docker-compose.yml deleted file mode 100644 index acbd50d523..0000000000 --- a/extra/redisotel/example/docker-compose.yml +++ /dev/null @@ -1,8 +0,0 @@ -version: '3.7' -services: - redis-server: - image: 'bitnami/redis:latest' - environment: - - ALLOW_EMPTY_PASSWORD=yes - ports: - - 6379:6379 diff --git a/extra/redisotel/example/go.mod b/extra/redisotel/example/go.mod deleted file mode 100644 index 1cbaf7fe98..0000000000 --- a/extra/redisotel/example/go.mod +++ /dev/null @@ -1,12 +0,0 @@ -module example - -go 1.16 - -require ( - github.com/go-redis/redis/extra/redisotel/v8 v8.8.2 - github.com/go-redis/redis/v8 v8.8.2 - go.opentelemetry.io/otel v1.0.0-RC1 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.0-RC1 - go.opentelemetry.io/otel/sdk v1.0.0-RC1 - go.opentelemetry.io/otel/sdk/metric v0.21.0 -) diff --git a/extra/redisotel/example/main.go b/extra/redisotel/example/main.go deleted file mode 100644 index 335eb8f27c..0000000000 --- a/extra/redisotel/example/main.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "context" - - "github.com/go-redis/redis/extra/redisotel/v8" - "github.com/go-redis/redis/v8" - "go.opentelemetry.io/otel" - stdoutexporter "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" - sdktrace "go.opentelemetry.io/otel/sdk/trace" -) - -var tracer = otel.Tracer("app_or_package_name") - -func main() { - exporter, err := stdoutexporter.New(stdoutexporter.WithPrettyPrint()) - if err != nil { - panic(err) - } - - provider := sdktrace.NewTracerProvider() - provider.RegisterSpanProcessor(sdktrace.NewSimpleSpanProcessor(exporter)) - - otel.SetTracerProvider(provider) - - rdb := redis.NewClient(&redis.Options{ - Addr: ":6379", - }) - defer rdb.Close() - - rdb.AddHook(redisotel.NewTracingHook()) - - ctx, span := tracer.Start(context.TODO(), "main") - defer span.End() - - if err := rdb.Ping(ctx).Err(); err != nil { - panic(err) - } -} diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod index 28ba2d98ae..144cf9c515 100644 --- a/extra/redisotel/go.mod +++ b/extra/redisotel/go.mod @@ -7,8 +7,9 @@ replace github.com/go-redis/redis/v8 => ../.. replace github.com/go-redis/redis/extra/rediscmd/v8 => ../rediscmd require ( - github.com/go-redis/redis/extra/rediscmd/v8 v8.8.2 - github.com/go-redis/redis/v8 v8.8.2 - go.opentelemetry.io/otel v1.0.0-RC1 - go.opentelemetry.io/otel/trace v1.0.0-RC1 + github.com/go-redis/redis/extra/rediscmd/v8 v8.11.5 + github.com/go-redis/redis/v8 v8.11.5 + go.opentelemetry.io/otel v1.5.0 + go.opentelemetry.io/otel/sdk v1.4.1 + go.opentelemetry.io/otel/trace v1.5.0 ) diff --git a/extra/redisotel/go.sum b/extra/redisotel/go.sum index 1aa1088b3a..1bcf1e7f33 100644 --- a/extra/redisotel/go.sum +++ b/extra/redisotel/go.sum @@ -1,57 +1,70 @@ -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= -github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= -github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v0.19.0 h1:Lenfy7QHRXPZVsw/12CWpxX6d/JkrX8wrx2vO8G80Ng= -go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg= -go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/metric v0.19.0 h1:dtZ1Ju44gkJkYvo+3qGqVXmf88tc+a42edOywypengg= -go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc= -go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.19.0 h1:YVfA0ByROYqTwOxqHVZYZExzEpfZor+MU1rU+ip2v9Q= -go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/trace v0.19.0 h1:1ucYlenXIDA1OlHVLDZKX0ObXV5RLaq06DtUKz5e5zc= -go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg= -go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4= +go.opentelemetry.io/otel v1.5.0 h1:DhCU8oR2sJH9rfnwPdoV/+BJ7UIN5kXHL8DuSGrPU8E= +go.opentelemetry.io/otel v1.5.0/go.mod h1:Jm/m+rNp/z0eqJc74H7LPwQ3G87qkU/AnnAydAjSAHk= +go.opentelemetry.io/otel/sdk v1.4.1 h1:J7EaW71E0v87qflB4cDolaqq3AcujGrtyIPGQoZOB0Y= +go.opentelemetry.io/otel/sdk v1.4.1/go.mod h1:NBwHDgDIBYjwK2WNu1OPgsIc2IJzmBXNnvIJxJc8BpE= +go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc= +go.opentelemetry.io/otel/trace v1.5.0 h1:AKQZ9zJsBRFAp7zLdyGNkqG2rToCDIt3i5tcLzQlbmU= +go.opentelemetry.io/otel/trace v1.5.0/go.mod h1:sq55kfhjXYr1zVSyexg0w1mpa03AYXR5eyTkB9NPPdE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -61,8 +74,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -72,13 +85,20 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -92,15 +112,19 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/extra/redisotel/redisotel.go b/extra/redisotel/redisotel.go index 3da61130d7..7015780673 100644 --- a/extra/redisotel/redisotel.go +++ b/extra/redisotel/redisotel.go @@ -3,39 +3,62 @@ package redisotel import ( "context" - "github.com/go-redis/redis/extra/rediscmd/v8" - "github.com/go-redis/redis/v8" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" "go.opentelemetry.io/otel/trace" + + "github.com/go-redis/redis/extra/rediscmd/v8" + "github.com/go-redis/redis/v8" ) -var tracer = otel.Tracer("github.com/go-redis/redis") +const ( + defaultTracerName = "github.com/go-redis/redis/extra/redisotel" +) -type TracingHook struct{} +type TracingHook struct { + tracer trace.Tracer + attrs []attribute.KeyValue +} -var _ redis.Hook = (*TracingHook)(nil) +func NewTracingHook(opts ...Option) *TracingHook { + cfg := &config{ + tp: otel.GetTracerProvider(), + attrs: []attribute.KeyValue{ + semconv.DBSystemRedis, + }, + } + for _, opt := range opts { + opt.apply(cfg) + } -func NewTracingHook() *TracingHook { - return new(TracingHook) + tracer := cfg.tp.Tracer( + defaultTracerName, + trace.WithInstrumentationVersion("semver:"+redis.Version()), + ) + return &TracingHook{tracer: tracer, attrs: cfg.attrs} } -func (TracingHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (context.Context, error) { +func (th *TracingHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (context.Context, error) { if !trace.SpanFromContext(ctx).IsRecording() { return ctx, nil } - ctx, span := tracer.Start(ctx, cmd.FullName()) - span.SetAttributes( - attribute.String("db.system", "redis"), - attribute.String("db.statement", rediscmd.CmdString(cmd)), - ) + opts := []trace.SpanStartOption{ + trace.WithSpanKind(trace.SpanKindClient), + trace.WithAttributes(th.attrs...), + trace.WithAttributes( + semconv.DBStatementKey.String(rediscmd.CmdString(cmd)), + ), + } + + ctx, _ = th.tracer.Start(ctx, cmd.FullName(), opts...) return ctx, nil } -func (TracingHook) AfterProcess(ctx context.Context, cmd redis.Cmder) error { +func (th *TracingHook) AfterProcess(ctx context.Context, cmd redis.Cmder) error { span := trace.SpanFromContext(ctx) if err := cmd.Err(); err != nil { recordError(ctx, span, err) @@ -44,24 +67,28 @@ func (TracingHook) AfterProcess(ctx context.Context, cmd redis.Cmder) error { return nil } -func (TracingHook) BeforeProcessPipeline(ctx context.Context, cmds []redis.Cmder) (context.Context, error) { +func (th *TracingHook) BeforeProcessPipeline(ctx context.Context, cmds []redis.Cmder) (context.Context, error) { if !trace.SpanFromContext(ctx).IsRecording() { return ctx, nil } summary, cmdsString := rediscmd.CmdsString(cmds) - ctx, span := tracer.Start(ctx, "pipeline "+summary) - span.SetAttributes( - attribute.String("db.system", "redis"), - attribute.Int("db.redis.num_cmd", len(cmds)), - attribute.String("db.statement", cmdsString), - ) + opts := []trace.SpanStartOption{ + trace.WithSpanKind(trace.SpanKindClient), + trace.WithAttributes(th.attrs...), + trace.WithAttributes( + semconv.DBStatementKey.String(cmdsString), + attribute.Int("db.redis.num_cmd", len(cmds)), + ), + } + + ctx, _ = th.tracer.Start(ctx, "pipeline "+summary, opts...) return ctx, nil } -func (TracingHook) AfterProcessPipeline(ctx context.Context, cmds []redis.Cmder) error { +func (th *TracingHook) AfterProcessPipeline(ctx context.Context, cmds []redis.Cmder) error { span := trace.SpanFromContext(ctx) if err := cmds[0].Err(); err != nil { recordError(ctx, span, err) @@ -76,3 +103,36 @@ func recordError(ctx context.Context, span trace.Span, err error) { span.SetStatus(codes.Error, err.Error()) } } + +type config struct { + tp trace.TracerProvider + attrs []attribute.KeyValue +} + +// Option specifies instrumentation configuration options. +type Option interface { + apply(*config) +} + +type optionFunc func(*config) + +func (o optionFunc) apply(c *config) { + o(c) +} + +// WithTracerProvider specifies a tracer provider to use for creating a tracer. +// If none is specified, the global provider is used. +func WithTracerProvider(provider trace.TracerProvider) Option { + return optionFunc(func(cfg *config) { + if provider != nil { + cfg.tp = provider + } + }) +} + +// WithAttributes specifies additional attributes to be added to the span. +func WithAttributes(attrs ...attribute.KeyValue) Option { + return optionFunc(func(cfg *config) { + cfg.attrs = append(cfg.attrs, attrs...) + }) +} diff --git a/extra/redisotel/redisotel_test.go b/extra/redisotel/redisotel_test.go new file mode 100644 index 0000000000..68aacc4a08 --- /dev/null +++ b/extra/redisotel/redisotel_test.go @@ -0,0 +1,68 @@ +package redisotel_test + +import ( + "context" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + "testing" + + "github.com/go-redis/redis/extra/redisotel/v8" + "github.com/go-redis/redis/v8" + "go.opentelemetry.io/otel" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/trace" +) + +func TestNew(t *testing.T) { + // this also functions as a compile-time test that the + // TracingHook conforms to the Hook interface + var _ redis.Hook = redisotel.NewTracingHook() +} + +type providerFunc func(name string, opts ...trace.TracerOption) trace.Tracer + +func (fn providerFunc) Tracer(name string, opts ...trace.TracerOption) trace.Tracer { + return fn(name, opts...) +} + +func TestNewWithTracerProvider(t *testing.T) { + invoked := false + + tp := providerFunc(func(name string, opts ...trace.TracerOption) trace.Tracer { + invoked = true + return otel.GetTracerProvider().Tracer(name, opts...) + }) + + _ = redisotel.NewTracingHook(redisotel.WithTracerProvider(tp)) + + if !invoked { + t.Fatalf("did not call custom TraceProvider") + } +} + +func TestNewWithAttributes(t *testing.T) { + provider := sdktrace.NewTracerProvider() + hook := redisotel.NewTracingHook(redisotel.WithTracerProvider(provider), redisotel.WithAttributes(semconv.NetPeerNameKey.String("localhost"))) + ctx, span := provider.Tracer("redis-test").Start(context.TODO(), "redis-test") + cmd := redis.NewCmd(ctx, "ping") + defer span.End() + + ctx, err := hook.BeforeProcess(ctx, cmd) + if err != nil { + t.Fatal(err) + } + err = hook.AfterProcess(ctx, cmd) + if err != nil { + t.Fatal(err) + } + + attrs := trace.SpanFromContext(ctx).(sdktrace.ReadOnlySpan).Attributes() + if !(attrs[0] == semconv.DBSystemRedis) { + t.Fatalf("expected attrs[0] to be semconv.DBSystemRedis, got: %v", attrs[0]) + } + if !(attrs[1] == semconv.NetPeerNameKey.String("localhost")) { + t.Fatalf("expected attrs[1] to be semconv.NetPeerNameKey.String(\"localhost\"), got: %v", attrs[1]) + } + if !(attrs[2] == semconv.DBStatementKey.String("ping")) { + t.Fatalf("expected attrs[2] to be semconv.DBStatementKey.String(\"ping\"), got: %v", attrs[2]) + } +} diff --git a/fuzz/fuzz.go b/fuzz/fuzz.go index c8497404f2..3225d24529 100644 --- a/fuzz/fuzz.go +++ b/fuzz/fuzz.go @@ -1,11 +1,13 @@ +//go:build gofuzz // +build gofuzz package fuzz import ( "context" - "github.com/go-redis/redis/v8" "time" + + "github.com/go-redis/redis/v8" ) var ( diff --git a/go.mod b/go.mod index c792cdd44c..d2610c2a02 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,20 @@ module github.com/go-redis/redis/v8 -go 1.14 +go 1.17 require ( - github.com/cespare/xxhash/v2 v2.1.1 + github.com/cespare/xxhash/v2 v2.1.2 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f - github.com/google/go-cmp v0.5.6 // indirect - github.com/onsi/ginkgo v1.15.0 - github.com/onsi/gomega v1.10.5 + github.com/onsi/ginkgo v1.16.5 + github.com/onsi/gomega v1.18.1 +) + +require ( + github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/nxadm/tail v1.4.8 // indirect + golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect + golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect + golang.org/x/text v0.3.6 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 76abf5b46c..e88f31a6c3 100644 --- a/go.sum +++ b/go.sum @@ -1,34 +1,51 @@ -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4= -github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ= -github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -39,8 +56,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -50,33 +67,42 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091 h1:DMyOG0U+gKfu8JZzg2UQe9MeaC1X+xQWlAKcRnjxjCw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/internal/hashtag/hashtag_test.go b/internal/hashtag/hashtag_test.go index 879e7bfe37..c0b6396f91 100644 --- a/internal/hashtag/hashtag_test.go +++ b/internal/hashtag/hashtag_test.go @@ -3,10 +3,10 @@ package hashtag import ( "testing" - "github.com/go-redis/redis/v8/internal/rand" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8/internal/rand" ) func TestGinkgoSuite(t *testing.T) { diff --git a/internal/hscan/hscan_test.go b/internal/hscan/hscan_test.go index 1f78bc7e02..ab4c0e1dc1 100644 --- a/internal/hscan/hscan_test.go +++ b/internal/hscan/hscan_test.go @@ -69,7 +69,7 @@ var _ = Describe("Scan", func() { Expect(Scan(&d, i{v}, i{vals[k]})).To(HaveOccurred()) } - //success + // success f = func(v uint64) string { return strconv.FormatUint(v, 10) } diff --git a/internal/hscan/structmap.go b/internal/hscan/structmap.go index 1b233258df..6839412ba2 100644 --- a/internal/hscan/structmap.go +++ b/internal/hscan/structmap.go @@ -39,12 +39,12 @@ func (s *structSpec) set(tag string, sf *structField) { } func newStructSpec(t reflect.Type, fieldTag string) *structSpec { + numField := t.NumField() out := &structSpec{ - m: make(map[string]*structField), + m: make(map[string]*structField, numField), } - num := t.NumField() - for i := 0; i < num; i++ { + for i := 0; i < numField; i++ { f := t.Field(i) tag := f.Tag.Get(fieldTag) diff --git a/internal/pool/conncheck.go b/internal/pool/conncheck.go deleted file mode 100644 index 5dd60dfa5f..0000000000 --- a/internal/pool/conncheck.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build linux darwin dragonfly freebsd netbsd openbsd solaris illumos - -package pool - -import ( - "errors" - "io" - "net" - "syscall" -) - -var errUnexpectedRead = errors.New("unexpected read from socket") - -func connCheck(conn net.Conn) error { - sysConn, ok := conn.(syscall.Conn) - if !ok { - return nil - } - rawConn, err := sysConn.SyscallConn() - if err != nil { - return err - } - - var sysErr error - err = rawConn.Read(func(fd uintptr) bool { - var buf [1]byte - n, err := syscall.Read(int(fd), buf[:]) - switch { - case n == 0 && err == nil: - sysErr = io.EOF - case n > 0: - sysErr = errUnexpectedRead - case err == syscall.EAGAIN || err == syscall.EWOULDBLOCK: - sysErr = nil - default: - sysErr = err - } - return true - }) - if err != nil { - return err - } - - return sysErr -} diff --git a/internal/pool/conncheck_dummy.go b/internal/pool/conncheck_dummy.go deleted file mode 100644 index 1daf98610e..0000000000 --- a/internal/pool/conncheck_dummy.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build !linux,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!illumos - -package pool - -import "net" - -func connCheck(conn net.Conn) error { - return nil -} diff --git a/internal/pool/conncheck_test.go b/internal/pool/conncheck_test.go deleted file mode 100644 index 0332174680..0000000000 --- a/internal/pool/conncheck_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build linux darwin dragonfly freebsd netbsd openbsd solaris illumos - -package pool - -import ( - "net" - "net/http/httptest" - "testing" - "time" -) - -func Test_connCheck(t *testing.T) { - // tests with real conns - ts := httptest.NewServer(nil) - defer ts.Close() - - t.Run("good conn", func(t *testing.T) { - conn, err := net.DialTimeout(ts.Listener.Addr().Network(), ts.Listener.Addr().String(), time.Second) - if err != nil { - t.Fatalf(err.Error()) - } - defer conn.Close() - if err = connCheck(conn); err != nil { - t.Fatalf(err.Error()) - } - conn.Close() - - if err = connCheck(conn); err == nil { - t.Fatalf("expect has error") - } - }) - - t.Run("bad conn 2", func(t *testing.T) { - conn, err := net.DialTimeout(ts.Listener.Addr().Network(), ts.Listener.Addr().String(), time.Second) - if err != nil { - t.Fatalf(err.Error()) - } - defer conn.Close() - - ts.Close() - - if err = connCheck(conn); err == nil { - t.Fatalf("expect has err") - } - }) -} diff --git a/internal/pool/export_test.go b/internal/pool/export_test.go index de7a644ea9..75dd4ad61c 100644 --- a/internal/pool/export_test.go +++ b/internal/pool/export_test.go @@ -1,6 +1,8 @@ package pool -import "time" +import ( + "time" +) func (cn *Conn) SetCreatedAt(tm time.Time) { cn.createdAt = tm diff --git a/internal/pool/main_test.go b/internal/pool/main_test.go index c54a38d514..2365dbc645 100644 --- a/internal/pool/main_test.go +++ b/internal/pool/main_test.go @@ -2,12 +2,9 @@ package pool_test import ( "context" - "fmt" "net" "sync" - "syscall" "testing" - "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -35,87 +32,5 @@ func perform(n int, cbs ...func(int)) { } func dummyDialer(context.Context) (net.Conn, error) { - // return &net.TCPConn{}, nil - return newDummyConn(), nil -} - -func newDummyConn() net.Conn { - return &dummyConn{ - rawConn: &dummyRawConn{}, - } -} - -var _ net.Conn = (*dummyConn)(nil) -var _ syscall.Conn = (*dummyConn)(nil) - -type dummyConn struct { - rawConn *dummyRawConn -} - -func (d *dummyConn) SyscallConn() (syscall.RawConn, error) { - return d.rawConn, nil -} - -var errDummy = fmt.Errorf("dummyConn err") - -func (d *dummyConn) Read(b []byte) (n int, err error) { - return 0, errDummy -} - -func (d *dummyConn) Write(b []byte) (n int, err error) { - return 0, errDummy -} - -func (d *dummyConn) Close() error { - d.rawConn.Close() - return nil -} - -func (d *dummyConn) LocalAddr() net.Addr { - return &net.TCPAddr{} -} - -func (d *dummyConn) RemoteAddr() net.Addr { - return &net.TCPAddr{} -} - -func (d *dummyConn) SetDeadline(t time.Time) error { - return nil -} - -func (d *dummyConn) SetReadDeadline(t time.Time) error { - return nil -} - -func (d *dummyConn) SetWriteDeadline(t time.Time) error { - return nil -} - -var _ syscall.RawConn = (*dummyRawConn)(nil) - -type dummyRawConn struct { - closed bool - mux sync.Mutex -} - -func (d *dummyRawConn) Control(f func(fd uintptr)) error { - return nil -} - -func (d *dummyRawConn) Read(f func(fd uintptr) (done bool)) error { - d.mux.Lock() - defer d.mux.Unlock() - if d.closed { - return fmt.Errorf("dummyRawConn closed") - } - return nil -} - -func (d *dummyRawConn) Write(f func(fd uintptr) (done bool)) error { - return nil -} -func (d *dummyRawConn) Close() { - d.mux.Lock() - d.closed = true - d.mux.Unlock() + return &net.TCPConn{}, nil } diff --git a/internal/pool/pool.go b/internal/pool/pool.go index 577923a79b..44a4e779df 100644 --- a/internal/pool/pool.go +++ b/internal/pool/pool.go @@ -121,9 +121,10 @@ func (p *ConnPool) checkMinIdleConns() { for p.poolSize < p.opt.PoolSize && p.idleConnsLen < p.opt.MinIdleConns { p.poolSize++ p.idleConnsLen++ + go func() { err := p.addIdleConn() - if err != nil { + if err != nil && err != ErrClosed { p.connsMu.Lock() p.poolSize-- p.idleConnsLen-- @@ -140,9 +141,16 @@ func (p *ConnPool) addIdleConn() error { } p.connsMu.Lock() + defer p.connsMu.Unlock() + + // It is not allowed to add new connections to the closed connection pool. + if p.closed() { + _ = cn.Close() + return ErrClosed + } + p.conns = append(p.conns, cn) p.idleConns = append(p.idleConns, cn) - p.connsMu.Unlock() return nil } @@ -157,6 +165,14 @@ func (p *ConnPool) newConn(ctx context.Context, pooled bool) (*Conn, error) { } p.connsMu.Lock() + defer p.connsMu.Unlock() + + // It is not allowed to add new connections to the closed connection pool. + if p.closed() { + _ = cn.Close() + return nil, ErrClosed + } + p.conns = append(p.conns, cn) if pooled { // If pool is full remove the cn on next Put. @@ -166,7 +182,6 @@ func (p *ConnPool) newConn(ctx context.Context, pooled bool) (*Conn, error) { p.poolSize++ } } - p.connsMu.Unlock() return cn, nil } @@ -237,9 +252,13 @@ func (p *ConnPool) Get(ctx context.Context) (*Conn, error) { for { p.connsMu.Lock() - cn := p.popIdle() + cn, err := p.popIdle() p.connsMu.Unlock() + if err != nil { + return nil, err + } + if cn == nil { break } @@ -308,10 +327,13 @@ func (p *ConnPool) freeTurn() { <-p.queue } -func (p *ConnPool) popIdle() *Conn { +func (p *ConnPool) popIdle() (*Conn, error) { + if p.closed() { + return nil, ErrClosed + } n := len(p.idleConns) if n == 0 { - return nil + return nil, nil } var cn *Conn @@ -326,7 +348,7 @@ func (p *ConnPool) popIdle() *Conn { } p.idleConnsLen-- p.checkMinIdleConns() - return cn + return cn, nil } func (p *ConnPool) Put(ctx context.Context, cn *Conn) { @@ -520,7 +542,7 @@ func (p *ConnPool) reapStaleConn() *Conn { func (p *ConnPool) isStaleConn(cn *Conn) bool { if p.opt.IdleTimeout == 0 && p.opt.MaxConnAge == 0 { - return connCheck(cn.netConn) != nil + return false } now := time.Now() @@ -531,5 +553,5 @@ func (p *ConnPool) isStaleConn(cn *Conn) bool { return true } - return connCheck(cn.netConn) != nil + return false } diff --git a/internal/pool/pool_test.go b/internal/pool/pool_test.go index 6c94fc27ac..423a783cbe 100644 --- a/internal/pool/pool_test.go +++ b/internal/pool/pool_test.go @@ -2,6 +2,7 @@ package pool_test import ( "context" + "net" "sync" "testing" "time" @@ -30,6 +31,43 @@ var _ = Describe("ConnPool", func() { connPool.Close() }) + It("should safe close", func() { + const minIdleConns = 10 + + var ( + wg sync.WaitGroup + closedChan = make(chan struct{}) + ) + wg.Add(minIdleConns) + connPool = pool.NewConnPool(&pool.Options{ + Dialer: func(ctx context.Context) (net.Conn, error) { + wg.Done() + <-closedChan + return &net.TCPConn{}, nil + }, + PoolSize: 10, + PoolTimeout: time.Hour, + IdleTimeout: time.Millisecond, + IdleCheckFrequency: time.Millisecond, + MinIdleConns: minIdleConns, + }) + wg.Wait() + Expect(connPool.Close()).NotTo(HaveOccurred()) + close(closedChan) + + // We wait for 1 second and believe that checkMinIdleConns has been executed. + time.Sleep(time.Second) + + Expect(connPool.Stats()).To(Equal(&pool.Stats{ + Hits: 0, + Misses: 0, + Timeouts: 0, + TotalConns: 0, + IdleConns: 0, + StaleConns: 0, + })) + }) + It("should unblock client when conn is removed", func() { // Reserve one connection. cn, err := connPool.Get(ctx) @@ -285,8 +323,6 @@ var _ = Describe("conns reaper", func() { cn.SetUsedAt(time.Now().Add(-2 * idleTimeout)) case "aged": cn.SetCreatedAt(time.Now().Add(-2 * maxAge)) - case "conncheck": - cn.Close() } conns = append(conns, cn) staleConns = append(staleConns, cn) @@ -373,7 +409,6 @@ var _ = Describe("conns reaper", func() { assert("idle") assert("aged") - assert("conncheck") }) var _ = Describe("race", func() { diff --git a/internal/proto/reader.go b/internal/proto/reader.go index 415e2d97b4..3ceedca93f 100644 --- a/internal/proto/reader.go +++ b/internal/proto/reader.go @@ -38,7 +38,7 @@ const ( //------------------------------------------------------------------------------ -const Nil = RedisError("redis: nil") +const Nil = RedisError("redis: nil") // nolint:errname type RedisError string diff --git a/internal/proto/scan.go b/internal/proto/scan.go index 7d7183c32d..0e994765fe 100644 --- a/internal/proto/scan.go +++ b/internal/proto/scan.go @@ -10,6 +10,7 @@ import ( ) // Scan parses bytes `b` to `v` with appropriate type. +//nolint:gocyclo func Scan(b []byte, v interface{}) error { switch v := v.(type) { case nil: @@ -105,6 +106,13 @@ func Scan(b []byte, v interface{}) error { var err error *v, err = time.Parse(time.RFC3339Nano, util.BytesToString(b)) return err + case *time.Duration: + n, err := util.ParseInt(b, 10, 64) + if err != nil { + return err + } + *v = time.Duration(n) + return nil case encoding.BinaryUnmarshaler: return v.UnmarshalBinary(b) default: diff --git a/internal/proto/scan_test.go b/internal/proto/scan_test.go index 5df3a6af61..55df550b54 100644 --- a/internal/proto/scan_test.go +++ b/internal/proto/scan_test.go @@ -3,9 +3,10 @@ package proto_test import ( "encoding/json" - "github.com/go-redis/redis/v8/internal/proto" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8/internal/proto" ) type testScanSliceStruct struct { diff --git a/internal/proto/writer.go b/internal/proto/writer.go index f2dc5c936a..690312e7af 100644 --- a/internal/proto/writer.go +++ b/internal/proto/writer.go @@ -98,6 +98,8 @@ func (w *Writer) WriteArg(v interface{}) error { case time.Time: w.numBuf = v.AppendFormat(w.numBuf[:0], time.RFC3339Nano) return w.bytes(w.numBuf) + case time.Duration: + return w.int(v.Nanoseconds()) case encoding.BinaryMarshaler: b, err := v.MarshalBinary() if err != nil { diff --git a/internal/proto/writer_test.go b/internal/proto/writer_test.go index c5df9a6f2b..ebae5692fc 100644 --- a/internal/proto/writer_test.go +++ b/internal/proto/writer_test.go @@ -6,10 +6,10 @@ import ( "testing" "time" - "github.com/go-redis/redis/v8/internal/proto" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8/internal/proto" ) type MyType struct{} @@ -51,7 +51,7 @@ var _ = Describe("WriteBuffer", func() { }) It("should append time", func() { - tm := time.Date(2019, 01, 01, 9, 45, 10, 222125, time.UTC) + tm := time.Date(2019, 1, 1, 9, 45, 10, 222125, time.UTC) err := wr.WriteArgs([]interface{}{tm}) Expect(err).NotTo(HaveOccurred()) diff --git a/internal/safe.go b/internal/safe.go index 862ff0eb3a..fd2f434094 100644 --- a/internal/safe.go +++ b/internal/safe.go @@ -1,3 +1,4 @@ +//go:build appengine // +build appengine package internal diff --git a/internal/unsafe.go b/internal/unsafe.go index 4bc79701f4..9f2e418f79 100644 --- a/internal/unsafe.go +++ b/internal/unsafe.go @@ -1,3 +1,4 @@ +//go:build !appengine // +build !appengine package internal diff --git a/internal/util/safe.go b/internal/util/safe.go index 1b3060ebc2..21307110bd 100644 --- a/internal/util/safe.go +++ b/internal/util/safe.go @@ -1,3 +1,4 @@ +//go:build appengine // +build appengine package util diff --git a/internal/util/unsafe.go b/internal/util/unsafe.go index c9868aac2b..daa8d7692a 100644 --- a/internal/util/unsafe.go +++ b/internal/util/unsafe.go @@ -1,3 +1,4 @@ +//go:build !appengine // +build !appengine package util diff --git a/iterator_test.go b/iterator_test.go index 7a64f0259d..68c8b77efe 100644 --- a/iterator_test.go +++ b/iterator_test.go @@ -3,10 +3,10 @@ package redis_test import ( "fmt" - "github.com/go-redis/redis/v8" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8" ) var _ = Describe("ScanIterator", func() { diff --git a/main_test.go b/main_test.go index dd9d87419f..5414310e71 100644 --- a/main_test.go +++ b/main_test.go @@ -117,7 +117,7 @@ func TestGinkgoSuite(t *testing.T) { RunSpecs(t, "go-redis") } -// ------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ func redisOptions() *redis.Options { return &redis.Options{ @@ -295,7 +295,7 @@ func redisDir(port string) (string, error) { if err := os.RemoveAll(dir); err != nil { return "", err } - if err := os.MkdirAll(dir, 0775); err != nil { + if err := os.MkdirAll(dir, 0o775); err != nil { return "", err } return dir, nil @@ -364,7 +364,7 @@ func startSentinel(port, masterName, masterPort string) (*redisProcess, error) { return p, nil } -// ------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ type badConnError string @@ -409,7 +409,7 @@ func (cn *badConn) Write([]byte) (int, error) { return 0, badConnError("bad connection") } -// ------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ type hook struct { beforeProcess func(ctx context.Context, cmd redis.Cmder) (context.Context, error) diff --git a/options.go b/options.go index e1e85a663e..52b35d6b4c 100644 --- a/options.go +++ b/options.go @@ -8,6 +8,7 @@ import ( "net" "net/url" "runtime" + "sort" "strconv" "strings" "time" @@ -192,9 +193,32 @@ func (opt *Options) clone() *Options { // Scheme is required. // There are two connection types: by tcp socket and by unix socket. // Tcp connection: -// redis://:@:/ +// redis://:@:/ // Unix connection: // unix://:@?db= +// Most Option fields can be set using query parameters, with the following restrictions: +// - field names are mapped using snake-case conversion: to set MaxRetries, use max_retries +// - only scalar type fields are supported (bool, int, time.Duration) +// - for time.Duration fields, values must be a valid input for time.ParseDuration(); +// additionally a plain integer as value (i.e. without unit) is intepreted as seconds +// - to disable a duration field, use value less than or equal to 0; to use the default +// value, leave the value blank or remove the parameter +// - only the last value is interpreted if a parameter is given multiple times +// - fields "network", "addr", "username" and "password" can only be set using other +// URL attributes (scheme, host, userinfo, resp.), query paremeters using these +// names will be treated as unknown parameters +// - unknown parameter names will result in an error +// Examples: +// redis://user:password@localhost:6789/3?dial_timeout=3&db=1&read_timeout=6s&max_retries=2 +// is equivalent to: +// &Options{ +// Network: "tcp", +// Addr: "localhost:6789", +// DB: 1, // path "/3" was overridden by "&db=1" +// DialTimeout: 3 * time.Second, // no time unit = seconds +// ReadTimeout: 6 * time.Second, +// MaxRetries: 2, +// } func ParseURL(redisURL string) (*Options, error) { u, err := url.Parse(redisURL) if err != nil { @@ -216,10 +240,6 @@ func setupTCPConn(u *url.URL) (*Options, error) { o.Username, o.Password = getUserPassword(u) - if len(u.Query()) > 0 { - return nil, errors.New("redis: no options supported") - } - h, p, err := net.SplitHostPort(u.Host) if err != nil { h = u.Host @@ -253,7 +273,7 @@ func setupTCPConn(u *url.URL) (*Options, error) { } } - return o, nil + return setupConnParams(u, o) } func setupUnixConn(u *url.URL) (*Options, error) { @@ -265,19 +285,122 @@ func setupUnixConn(u *url.URL) (*Options, error) { return nil, errors.New("redis: empty unix socket path") } o.Addr = u.Path - o.Username, o.Password = getUserPassword(u) + return setupConnParams(u, o) +} - dbStr := u.Query().Get("db") - if dbStr == "" { - return o, nil // if database is not set, connect to 0 db. +type queryOptions struct { + q url.Values + err error +} + +func (o *queryOptions) string(name string) string { + vs := o.q[name] + if len(vs) == 0 { + return "" } + delete(o.q, name) // enable detection of unknown parameters + return vs[len(vs)-1] +} - db, err := strconv.Atoi(dbStr) - if err != nil { - return nil, fmt.Errorf("redis: invalid database number: %w", err) +func (o *queryOptions) int(name string) int { + s := o.string(name) + if s == "" { + return 0 + } + i, err := strconv.Atoi(s) + if err == nil { + return i + } + if o.err == nil { + o.err = fmt.Errorf("redis: invalid %s number: %s", name, err) + } + return 0 +} + +func (o *queryOptions) duration(name string) time.Duration { + s := o.string(name) + if s == "" { + return 0 + } + // try plain number first + if i, err := strconv.Atoi(s); err == nil { + if i <= 0 { + // disable timeouts + return -1 + } + return time.Duration(i) * time.Second + } + dur, err := time.ParseDuration(s) + if err == nil { + return dur + } + if o.err == nil { + o.err = fmt.Errorf("redis: invalid %s duration: %w", name, err) + } + return 0 +} + +func (o *queryOptions) bool(name string) bool { + switch s := o.string(name); s { + case "true", "1": + return true + case "false", "0", "": + return false + default: + if o.err == nil { + o.err = fmt.Errorf("redis: invalid %s boolean: expected true/false/1/0 or an empty string, got %q", name, s) + } + return false + } +} + +func (o *queryOptions) remaining() []string { + if len(o.q) == 0 { + return nil + } + keys := make([]string, 0, len(o.q)) + for k := range o.q { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + +// setupConnParams converts query parameters in u to option value in o. +func setupConnParams(u *url.URL, o *Options) (*Options, error) { + q := queryOptions{q: u.Query()} + + // compat: a future major release may use q.int("db") + if tmp := q.string("db"); tmp != "" { + db, err := strconv.Atoi(tmp) + if err != nil { + return nil, fmt.Errorf("redis: invalid database number: %w", err) + } + o.DB = db + } + + o.MaxRetries = q.int("max_retries") + o.MinRetryBackoff = q.duration("min_retry_backoff") + o.MaxRetryBackoff = q.duration("max_retry_backoff") + o.DialTimeout = q.duration("dial_timeout") + o.ReadTimeout = q.duration("read_timeout") + o.WriteTimeout = q.duration("write_timeout") + o.PoolFIFO = q.bool("pool_fifo") + o.PoolSize = q.int("pool_size") + o.MinIdleConns = q.int("min_idle_conns") + o.MaxConnAge = q.duration("max_conn_age") + o.PoolTimeout = q.duration("pool_timeout") + o.IdleTimeout = q.duration("idle_timeout") + o.IdleCheckFrequency = q.duration("idle_check_frequency") + if q.err != nil { + return nil, q.err + } + + // any parameters left? + if r := q.remaining(); len(r) > 0 { + return nil, fmt.Errorf("redis: unexpected option: %s", strings.Join(r, ", ")) } - o.DB = db return o, nil } diff --git a/options_test.go b/options_test.go index 9ffc6fcae6..145052394a 100644 --- a/options_test.go +++ b/options_test.go @@ -1,8 +1,10 @@ +//go:build go1.7 // +build go1.7 package redis import ( + "crypto/tls" "errors" "testing" "time" @@ -10,150 +12,185 @@ import ( func TestParseURL(t *testing.T) { cases := []struct { - u string - addr string - db int - tls bool - err error - user string - pass string + url string + o *Options // expected value + err error }{ { - "redis://localhost:123/1", - "localhost:123", - 1, false, nil, - "", "", - }, - { - "redis://localhost:123", - "localhost:123", - 0, false, nil, - "", "", - }, - { - "redis://localhost/1", - "localhost:6379", - 1, false, nil, - "", "", - }, - { - "redis://12345", - "12345:6379", - 0, false, nil, - "", "", - }, - { - "rediss://localhost:123", - "localhost:123", - 0, true, nil, - "", "", - }, - { - "redis://:bar@localhost:123", - "localhost:123", - 0, false, nil, - "", "bar", - }, - { - "redis://foo@localhost:123", - "localhost:123", - 0, false, nil, - "foo", "", - }, - { - "redis://foo:bar@localhost:123", - "localhost:123", - 0, false, nil, - "foo", "bar", - }, - { - "unix:///tmp/redis.sock", - "/tmp/redis.sock", - 0, false, nil, - "", "", - }, - { - "unix://foo:bar@/tmp/redis.sock", - "/tmp/redis.sock", - 0, false, nil, - "foo", "bar", - }, - { - "unix://foo:bar@/tmp/redis.sock?db=3", - "/tmp/redis.sock", - 3, false, nil, - "foo", "bar", - }, - { - "unix://foo:bar@/tmp/redis.sock?db=test", - "/tmp/redis.sock", - 0, false, errors.New("redis: invalid database number: strconv.Atoi: parsing \"test\": invalid syntax"), - "", "", - }, - { - "redis://localhost/?abc=123", - "", - 0, false, errors.New("redis: no options supported"), - "", "", - }, - { - "http://google.com", - "", - 0, false, errors.New("redis: invalid URL scheme: http"), - "", "", - }, - { - "redis://localhost/1/2/3/4", - "", - 0, false, errors.New("redis: invalid URL path: /1/2/3/4"), - "", "", - }, - { - "12345", - "", - 0, false, errors.New("redis: invalid URL scheme: "), - "", "", - }, - { - "redis://localhost/iamadatabase", - "", - 0, false, errors.New(`redis: invalid database number: "iamadatabase"`), - "", "", + url: "redis://localhost:123/1", + o: &Options{Addr: "localhost:123", DB: 1}, + }, { + url: "redis://localhost:123", + o: &Options{Addr: "localhost:123"}, + }, { + url: "redis://localhost/1", + o: &Options{Addr: "localhost:6379", DB: 1}, + }, { + url: "redis://12345", + o: &Options{Addr: "12345:6379"}, + }, { + url: "rediss://localhost:123", + o: &Options{Addr: "localhost:123", TLSConfig: &tls.Config{ /* no deep comparison */ }}, + }, { + url: "redis://:bar@localhost:123", + o: &Options{Addr: "localhost:123", Password: "bar"}, + }, { + url: "redis://foo@localhost:123", + o: &Options{Addr: "localhost:123", Username: "foo"}, + }, { + url: "redis://foo:bar@localhost:123", + o: &Options{Addr: "localhost:123", Username: "foo", Password: "bar"}, + }, { + // multiple params + url: "redis://localhost:123/?db=2&read_timeout=2&pool_fifo=true", + o: &Options{Addr: "localhost:123", DB: 2, ReadTimeout: 2 * time.Second, PoolFIFO: true}, + }, { + // special case handling for disabled timeouts + url: "redis://localhost:123/?db=2&idle_timeout=0", + o: &Options{Addr: "localhost:123", DB: 2, IdleTimeout: -1}, + }, { + // negative values disable timeouts as well + url: "redis://localhost:123/?db=2&idle_timeout=-1", + o: &Options{Addr: "localhost:123", DB: 2, IdleTimeout: -1}, + }, { + // absent timeout values will use defaults + url: "redis://localhost:123/?db=2&idle_timeout=", + o: &Options{Addr: "localhost:123", DB: 2, IdleTimeout: 0}, + }, { + url: "redis://localhost:123/?db=2&idle_timeout", // missing "=" at the end + o: &Options{Addr: "localhost:123", DB: 2, IdleTimeout: 0}, + }, { + url: "unix:///tmp/redis.sock", + o: &Options{Addr: "/tmp/redis.sock"}, + }, { + url: "unix://foo:bar@/tmp/redis.sock", + o: &Options{Addr: "/tmp/redis.sock", Username: "foo", Password: "bar"}, + }, { + url: "unix://foo:bar@/tmp/redis.sock?db=3", + o: &Options{Addr: "/tmp/redis.sock", Username: "foo", Password: "bar", DB: 3}, + }, { + // invalid db format + url: "unix://foo:bar@/tmp/redis.sock?db=test", + err: errors.New(`redis: invalid database number: strconv.Atoi: parsing "test": invalid syntax`), + }, { + // invalid int value + url: "redis://localhost/?pool_size=five", + err: errors.New(`redis: invalid pool_size number: strconv.Atoi: parsing "five": invalid syntax`), + }, { + // invalid bool value + url: "redis://localhost/?pool_fifo=yes", + err: errors.New(`redis: invalid pool_fifo boolean: expected true/false/1/0 or an empty string, got "yes"`), + }, { + // it returns first error + url: "redis://localhost/?db=foo&pool_size=five", + err: errors.New(`redis: invalid database number: strconv.Atoi: parsing "foo": invalid syntax`), + }, { + url: "redis://localhost/?abc=123", + err: errors.New("redis: unexpected option: abc"), + }, { + url: "redis://foo@localhost/?username=bar", + err: errors.New("redis: unexpected option: username"), + }, { + url: "redis://localhost/?wrte_timout=10s&abc=123", + err: errors.New("redis: unexpected option: abc, wrte_timout"), + }, { + url: "http://google.com", + err: errors.New("redis: invalid URL scheme: http"), + }, { + url: "redis://localhost/1/2/3/4", + err: errors.New("redis: invalid URL path: /1/2/3/4"), + }, { + url: "12345", + err: errors.New("redis: invalid URL scheme: "), + }, { + url: "redis://localhost/iamadatabase", + err: errors.New(`redis: invalid database number: "iamadatabase"`), }, } - for _, c := range cases { - t.Run(c.u, func(t *testing.T) { - o, err := ParseURL(c.u) - if c.err == nil && err != nil { + for i := range cases { + tc := cases[i] + t.Run(tc.url, func(t *testing.T) { + t.Parallel() + + actual, err := ParseURL(tc.url) + if tc.err == nil && err != nil { t.Fatalf("unexpected error: %q", err) return } - if c.err != nil && err != nil { - if c.err.Error() != err.Error() { - t.Fatalf("got %q, expected %q", err, c.err) + if tc.err != nil && err != nil { + if tc.err.Error() != err.Error() { + t.Fatalf("got %q, expected %q", err, tc.err) } return } - if o.Addr != c.addr { - t.Errorf("got %q, want %q", o.Addr, c.addr) - } - if o.DB != c.db { - t.Errorf("got %q, expected %q", o.DB, c.db) - } - if c.tls && o.TLSConfig == nil { - t.Errorf("got nil TLSConfig, expected a TLSConfig") - } - if o.Username != c.user { - t.Errorf("got %q, expected %q", o.Username, c.user) - } - if o.Password != c.pass { - t.Errorf("got %q, expected %q", o.Password, c.pass) - } + comprareOptions(t, actual, tc.o) }) } } +func comprareOptions(t *testing.T, actual, expected *Options) { + t.Helper() + + if actual.Addr != expected.Addr { + t.Errorf("got %q, want %q", actual.Addr, expected.Addr) + } + if actual.DB != expected.DB { + t.Errorf("DB: got %q, expected %q", actual.DB, expected.DB) + } + if actual.TLSConfig == nil && expected.TLSConfig != nil { + t.Errorf("got nil TLSConfig, expected a TLSConfig") + } + if actual.TLSConfig != nil && expected.TLSConfig == nil { + t.Errorf("got TLSConfig, expected no TLSConfig") + } + if actual.Username != expected.Username { + t.Errorf("Username: got %q, expected %q", actual.Username, expected.Username) + } + if actual.Password != expected.Password { + t.Errorf("Password: got %q, expected %q", actual.Password, expected.Password) + } + if actual.MaxRetries != expected.MaxRetries { + t.Errorf("MaxRetries: got %v, expected %v", actual.MaxRetries, expected.MaxRetries) + } + if actual.MinRetryBackoff != expected.MinRetryBackoff { + t.Errorf("MinRetryBackoff: got %v, expected %v", actual.MinRetryBackoff, expected.MinRetryBackoff) + } + if actual.MaxRetryBackoff != expected.MaxRetryBackoff { + t.Errorf("MaxRetryBackoff: got %v, expected %v", actual.MaxRetryBackoff, expected.MaxRetryBackoff) + } + if actual.DialTimeout != expected.DialTimeout { + t.Errorf("DialTimeout: got %v, expected %v", actual.DialTimeout, expected.DialTimeout) + } + if actual.ReadTimeout != expected.ReadTimeout { + t.Errorf("ReadTimeout: got %v, expected %v", actual.ReadTimeout, expected.ReadTimeout) + } + if actual.WriteTimeout != expected.WriteTimeout { + t.Errorf("WriteTimeout: got %v, expected %v", actual.WriteTimeout, expected.WriteTimeout) + } + if actual.PoolFIFO != expected.PoolFIFO { + t.Errorf("PoolFIFO: got %v, expected %v", actual.PoolFIFO, expected.PoolFIFO) + } + if actual.PoolSize != expected.PoolSize { + t.Errorf("PoolSize: got %v, expected %v", actual.PoolSize, expected.PoolSize) + } + if actual.MinIdleConns != expected.MinIdleConns { + t.Errorf("MinIdleConns: got %v, expected %v", actual.MinIdleConns, expected.MinIdleConns) + } + if actual.MaxConnAge != expected.MaxConnAge { + t.Errorf("MaxConnAge: got %v, expected %v", actual.MaxConnAge, expected.MaxConnAge) + } + if actual.PoolTimeout != expected.PoolTimeout { + t.Errorf("PoolTimeout: got %v, expected %v", actual.PoolTimeout, expected.PoolTimeout) + } + if actual.IdleTimeout != expected.IdleTimeout { + t.Errorf("IdleTimeout: got %v, expected %v", actual.IdleTimeout, expected.IdleTimeout) + } + if actual.IdleCheckFrequency != expected.IdleCheckFrequency { + t.Errorf("IdleCheckFrequency: got %v, expected %v", actual.IdleCheckFrequency, expected.IdleCheckFrequency) + } +} + // Test ReadTimeout option initialization, including special values -1 and 0. // And also test behaviour of WriteTimeout option, when it is not explicitly set and use // ReadTimeout value. diff --git a/package.json b/package.json new file mode 100644 index 0000000000..e4ea4bb074 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "name": "redis", + "version": "8.11.5", + "main": "index.js", + "repository": "git@github.com:go-redis/redis.git", + "author": "Vladimir Mihailenco ", + "license": "BSD-2-clause" +} diff --git a/pipeline.go b/pipeline.go index aa2fc8f03e..b9845ba33e 100644 --- a/pipeline.go +++ b/pipeline.go @@ -22,6 +22,7 @@ type pipelineExecer func(context.Context, []Cmder) error // depends of your batch size and/or use TxPipeline. type Pipeliner interface { StatefulCmdable + Len() int Do(ctx context.Context, args ...interface{}) *Cmd Process(ctx context.Context, cmd Cmder) error Discard() @@ -49,6 +50,15 @@ func (c *Pipeline) init() { c.statefulCmdable = c.Process } +// Len returns the number of queued commands. +func (c *Pipeline) Len() int { + c.mu.Lock() + ln := len(c.cmds) + c.mu.Unlock() + return ln +} + +// Do queues the custom command for later execution. func (c *Pipeline) Do(ctx context.Context, args ...interface{}) *Cmd { cmd := NewCmd(ctx, args...) _ = c.Process(ctx, cmd) diff --git a/pipeline_test.go b/pipeline_test.go index 9d2a60cfc4..f24114d72a 100644 --- a/pipeline_test.go +++ b/pipeline_test.go @@ -3,10 +3,10 @@ package redis_test import ( "strconv" - "github.com/go-redis/redis/v8" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8" ) var _ = Describe("pipelining", func() { diff --git a/pool_test.go b/pool_test.go index 5e83549c5c..e297b010d6 100644 --- a/pool_test.go +++ b/pool_test.go @@ -4,10 +4,10 @@ import ( "context" "time" - "github.com/go-redis/redis/v8" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8" ) var _ = Describe("pool", func() { @@ -86,9 +86,8 @@ var _ = Describe("pool", func() { cn.SetNetConn(&badConn{}) client.Pool().Put(ctx, cn) - // connCheck will automatically remove damaged connections. err = client.Ping(ctx).Err() - Expect(err).NotTo(HaveOccurred()) + Expect(err).To(MatchError("bad connection")) val, err := client.Ping(ctx).Result() Expect(err).NotTo(HaveOccurred()) diff --git a/pubsub.go b/pubsub.go index c6ffb25622..efc2354af0 100644 --- a/pubsub.go +++ b/pubsub.go @@ -141,7 +141,7 @@ func (c *PubSub) releaseConn(ctx context.Context, cn *pool.Conn, err error, allo if c.cn != cn { return } - if isBadConn(err, allowTimeout) { + if isBadConn(err, allowTimeout, c.opt.Addr) { c.reconnect(ctx, err) } } @@ -252,13 +252,16 @@ func (c *PubSub) Ping(ctx context.Context, payload ...string) error { } cmd := NewCmd(ctx, args...) - cn, err := c.connWithLock(ctx) + c.mu.Lock() + defer c.mu.Unlock() + + cn, err := c.conn(ctx, nil) if err != nil { return err } err = c.writeCmd(ctx, cn, cmd) - c.releaseConnWithLock(ctx, cn, err, false) + c.releaseConn(ctx, cn, err, false) return err } @@ -361,6 +364,8 @@ func (c *PubSub) ReceiveTimeout(ctx context.Context, timeout time.Duration) (int c.cmd = NewCmd(ctx) } + // Don't hold the lock to allow subscriptions and pings. + cn, err := c.connWithLock(ctx) if err != nil { return nil, err @@ -371,6 +376,7 @@ func (c *PubSub) ReceiveTimeout(ctx context.Context, timeout time.Duration) (int }) c.releaseConnWithLock(ctx, cn, err, timeout > 0) + if err != nil { return nil, err } diff --git a/pubsub_test.go b/pubsub_test.go index 14e37c2be3..5776bbde43 100644 --- a/pubsub_test.go +++ b/pubsub_test.go @@ -6,10 +6,10 @@ import ( "sync" "time" - "github.com/go-redis/redis/v8" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8" ) var _ = Describe("PubSub", func() { diff --git a/race_test.go b/race_test.go index a1c2a08049..34699d1327 100644 --- a/race_test.go +++ b/race_test.go @@ -10,10 +10,10 @@ import ( "testing" "time" - "github.com/go-redis/redis/v8" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8" ) var _ = Describe("races", func() { @@ -373,6 +373,18 @@ var _ = Describe("cluster races", func() { Expect(err).NotTo(HaveOccurred()) Expect(val).To(Equal(int64(C * N))) }) + + It("write cmd data-race", func() { + pubsub := client.Subscribe(ctx) + defer pubsub.Close() + + pubsub.Channel(redis.WithChannelHealthCheckInterval(time.Millisecond)) + for i := 0; i < 100; i++ { + key := fmt.Sprintf("channel_%d", i) + pubsub.Subscribe(ctx, key) + pubsub.Unsubscribe(ctx, key) + } + }) }) func bigVal() []byte { diff --git a/redis.go b/redis.go index 051fa59455..919c1642a4 100644 --- a/redis.go +++ b/redis.go @@ -15,6 +15,7 @@ import ( // Nil reply returned by Redis when key does not exist. const Nil = proto.Nil +// SetLogger set custom log func SetLogger(logger internal.Logging) { internal.Logger = logger } @@ -51,9 +52,7 @@ func (hs hooks) process( ctx context.Context, cmd Cmder, fn func(context.Context, Cmder) error, ) error { if len(hs.hooks) == 0 { - err := hs.withContext(ctx, func() error { - return fn(ctx, cmd) - }) + err := fn(ctx, cmd) cmd.SetErr(err) return err } @@ -69,9 +68,7 @@ func (hs hooks) process( } if retErr == nil { - retErr = hs.withContext(ctx, func() error { - return fn(ctx, cmd) - }) + retErr = fn(ctx, cmd) cmd.SetErr(retErr) } @@ -89,9 +86,7 @@ func (hs hooks) processPipeline( ctx context.Context, cmds []Cmder, fn func(context.Context, []Cmder) error, ) error { if len(hs.hooks) == 0 { - err := hs.withContext(ctx, func() error { - return fn(ctx, cmds) - }) + err := fn(ctx, cmds) return err } @@ -106,9 +101,7 @@ func (hs hooks) processPipeline( } if retErr == nil { - retErr = hs.withContext(ctx, func() error { - return fn(ctx, cmds) - }) + retErr = fn(ctx, cmds) } for hookIndex--; hookIndex >= 0; hookIndex-- { @@ -128,10 +121,6 @@ func (hs hooks) processTxPipeline( return hs.processPipeline(ctx, cmds, fn) } -func (hs hooks) withContext(_ context.Context, fn func() error) error { - return fn() -} - //------------------------------------------------------------------------------ type baseClient struct { @@ -277,7 +266,7 @@ func (c *baseClient) releaseConn(ctx context.Context, cn *pool.Conn, err error) c.opt.Limiter.ReportResult(err) } - if isBadConn(err, false) { + if isBadConn(err, false, c.opt.Addr) { c.connPool.Remove(ctx, cn, err) } else { c.connPool.Put(ctx, cn) @@ -722,11 +711,9 @@ type conn struct { hooks // TODO: inherit hooks } -// Conn represents a single Redis connection rather than a pool of database connections. -// It's safe for concurrent use by multiple goroutines. -// -// Prefer running commands from Client unless there is a specific need for a continuous -// single Redis connection. +// Conn represents a single Redis connection rather than a pool of connections. +// Prefer running commands from Client unless there is a specific need +// for a continuous single Redis connection. type Conn struct { *conn ctx context.Context diff --git a/redis_test.go b/redis_test.go index c2d2dc023b..02daa3cfd0 100644 --- a/redis_test.go +++ b/redis_test.go @@ -8,10 +8,10 @@ import ( "testing" "time" - "github.com/go-redis/redis/v8" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8" ) type redisHookError struct { @@ -283,6 +283,18 @@ var _ = Describe("Client", func() { Expect(tm2).To(BeTemporally("==", tm)) }) + It("should set and scan durations", func() { + duration := 10 * time.Minute + err := client.Set(ctx, "duration", duration, 0).Err() + Expect(err).NotTo(HaveOccurred()) + + var duration2 time.Duration + err = client.Get(ctx, "duration").Scan(&duration2) + Expect(err).NotTo(HaveOccurred()) + + Expect(duration2).To(Equal(duration)) + }) + It("should Conn", func() { err := client.Conn(ctx).Get(ctx, "this-key-does-not-exist").Err() Expect(err).To(Equal(redis.Nil)) diff --git a/ring.go b/ring.go index 7446d32c24..8309cbe4e9 100644 --- a/ring.go +++ b/ring.go @@ -12,7 +12,8 @@ import ( "time" "github.com/cespare/xxhash/v2" - "github.com/dgryski/go-rendezvous" + rendezvous "github.com/dgryski/go-rendezvous" //nolint + "github.com/go-redis/redis/v8/internal" "github.com/go-redis/redis/v8/internal/hashtag" "github.com/go-redis/redis/v8/internal/pool" @@ -575,7 +576,7 @@ func (c *Ring) cmdInfo(ctx context.Context, name string) *CommandInfo { } info := cmdsInfo[name] if info == nil { - internal.Logger.Printf(c.Context(), "info for cmd=%s not found", name) + internal.Logger.Printf(ctx, "info for cmd=%s not found", name) } return info } diff --git a/ring_test.go b/ring_test.go index 432a1c0704..b0705c5b8a 100644 --- a/ring_test.go +++ b/ring_test.go @@ -9,10 +9,10 @@ import ( "sync" "time" - "github.com/go-redis/redis/v8" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8" ) var _ = Describe("Redis Ring", func() { @@ -190,8 +190,8 @@ var _ = Describe("Redis Ring", func() { Describe("Process hook", func() { BeforeEach(func() { - //the health check leads to data race for variable "stack []string". - //here, the health check time is set to 72 hours to avoid health check + // the health check leads to data race for variable "stack []string". + // here, the health check time is set to 72 hours to avoid health check opt := redisRingOptions() opt.HeartbeatFrequency = 72 * time.Hour ring = redis.NewRing(opt) diff --git a/scripts/bump_deps.sh b/scripts/bump_deps.sh new file mode 100755 index 0000000000..f294c4f117 --- /dev/null +++ b/scripts/bump_deps.sh @@ -0,0 +1,9 @@ +PACKAGE_DIRS=$(find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; \ + | sed 's/^\.\///' \ + | sort) + +for dir in $PACKAGE_DIRS +do + printf "${dir}: go get -d && go mod tidy\n" + (cd ./${dir} && go get -d && go mod tidy) +done diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000000..2e78be61b5 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +set -e + +help() { + cat <<- EOF +Usage: TAG=tag $0 + +Updates version in go.mod files and pushes a new brash to GitHub. + +VARIABLES: + TAG git tag, for example, v1.0.0 +EOF + exit 0 +} + +if [ -z "$TAG" ] +then + printf "TAG is required\n\n" + help +fi + +TAG_REGEX="^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$" +if ! [[ "${TAG}" =~ ${TAG_REGEX} ]]; then + printf "TAG is not valid: ${TAG}\n\n" + exit 1 +fi + +TAG_FOUND=`git tag --list ${TAG}` +if [[ ${TAG_FOUND} = ${TAG} ]] ; then + printf "tag ${TAG} already exists\n\n" + exit 1 +fi + +if ! git diff --quiet +then + printf "working tree is not clean\n\n" + git status + exit 1 +fi + +git checkout master + +PACKAGE_DIRS=$(find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; \ + | sed 's/^\.\///' \ + | sort) + +for dir in $PACKAGE_DIRS +do + printf "${dir}: go get -u && go mod tidy\n" + (cd ./${dir} && go get -u && go mod tidy) +done + +for dir in $PACKAGE_DIRS +do + sed --in-place \ + "s/go-redis\/redis\([^ ]*\) v.*/go-redis\/redis\1 ${TAG}/" "${dir}/go.mod" + (cd ./${dir} && go get -u && go mod tidy) +done + +sed --in-place "s/\(return \)\"[^\"]*\"/\1\"${TAG#v}\"/" ./version.go +sed --in-place "s/\(\"version\": \)\"[^\"]*\"/\1\"${TAG#v}\"/" ./package.json + +conventional-changelog -p angular -i CHANGELOG.md -s + +git checkout -b release/${TAG} master +git add -u +git commit -m "chore: release $TAG (release.sh)" +git push origin release/${TAG} diff --git a/scripts/tag.sh b/scripts/tag.sh new file mode 100755 index 0000000000..121f00e0c8 --- /dev/null +++ b/scripts/tag.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +set -e + +help() { + cat <<- EOF +Usage: TAG=tag $0 + +Creates git tags for public Go packages. + +VARIABLES: + TAG git tag, for example, v1.0.0 +EOF + exit 0 +} + +if [ -z "$TAG" ] +then + printf "TAG env var is required\n\n"; + help +fi + +if ! grep -Fq "\"${TAG#v}\"" version.go +then + printf "version.go does not contain ${TAG#v}\n" + exit 1 +fi + +PACKAGE_DIRS=$(find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \; \ + | grep -E -v "example|internal" \ + | sed 's/^\.\///' \ + | sort) + +git tag ${TAG} +git push origin ${TAG} + +for dir in $PACKAGE_DIRS +do + printf "tagging ${dir}/${TAG}\n" + git tag ${dir}/${TAG} + git push origin ${dir}/${TAG} +done diff --git a/sentinel.go b/sentinel.go index 361f229ea3..205f8a123b 100644 --- a/sentinel.go +++ b/sentinel.go @@ -23,7 +23,13 @@ type FailoverOptions struct { MasterName string // A seed list of host:port addresses of sentinel nodes. SentinelAddrs []string - // Sentinel password from "requirepass " (if enabled) in Sentinel configuration + + // If specified with SentinelPassword, enables ACL-based authentication (via + // AUTH ). + SentinelUsername string + // Sentinel password from "requirepass " (if enabled) in Sentinel + // configuration, or, if SentinelUsername is also supplied, used for ACL-based + // authentication. SentinelPassword string // Allows routing read-only commands to the closest master or slave node. @@ -109,6 +115,7 @@ func (opt *FailoverOptions) sentinelOptions(addr string) *Options { OnConnect: opt.OnConnect, DB: 0, + Username: opt.SentinelUsername, Password: opt.SentinelPassword, MaxRetries: opt.MaxRetries, diff --git a/sentinel_test.go b/sentinel_test.go index 12e734da82..cc56cbabac 100644 --- a/sentinel_test.go +++ b/sentinel_test.go @@ -3,10 +3,10 @@ package redis_test import ( "net" - "github.com/go-redis/redis/v8" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8" ) var _ = Describe("Sentinel", func() { @@ -192,7 +192,7 @@ var _ = Describe("NewFailoverClusterClient", func() { err = master.Shutdown(ctx).Err() Expect(err).NotTo(HaveOccurred()) Eventually(func() error { - return master.Ping(ctx).Err() + return sentinelMaster.Ping(ctx).Err() }, "15s", "100ms").Should(HaveOccurred()) // Check that client picked up new master. @@ -214,3 +214,76 @@ var _ = Describe("NewFailoverClusterClient", func() { Expect(err).NotTo(HaveOccurred()) }) }) + +var _ = Describe("SentinelAclAuth", func() { + const ( + aclSentinelUsername = "sentinel-user" + aclSentinelPassword = "sentinel-pass" + ) + + var client *redis.Client + var sentinel *redis.SentinelClient + var sentinels = func() []*redisProcess { + return []*redisProcess{sentinel1, sentinel2, sentinel3} + } + + BeforeEach(func() { + authCmd := redis.NewStatusCmd(ctx, "ACL", "SETUSER", aclSentinelUsername, "ON", + ">"+aclSentinelPassword, "-@all", "+auth", "+client|getname", "+client|id", "+client|setname", + "+command", "+hello", "+ping", "+role", "+sentinel|get-master-addr-by-name", "+sentinel|master", + "+sentinel|myid", "+sentinel|replicas", "+sentinel|sentinels") + + for _, process := range sentinels() { + err := process.Client.Process(ctx, authCmd) + Expect(err).NotTo(HaveOccurred()) + } + + client = redis.NewFailoverClient(&redis.FailoverOptions{ + MasterName: sentinelName, + SentinelAddrs: sentinelAddrs, + MaxRetries: -1, + SentinelUsername: aclSentinelUsername, + SentinelPassword: aclSentinelPassword, + }) + + Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred()) + + sentinel = redis.NewSentinelClient(&redis.Options{ + Addr: sentinelAddrs[0], + MaxRetries: -1, + Username: aclSentinelUsername, + Password: aclSentinelPassword, + }) + + _, err := sentinel.GetMasterAddrByName(ctx, sentinelName).Result() + Expect(err).NotTo(HaveOccurred()) + + // Wait until sentinels are picked up by each other. + for _, process := range sentinels() { + Eventually(func() string { + return process.Info(ctx).Val() + }, "15s", "100ms").Should(ContainSubstring("sentinels=3")) + } + }) + + AfterEach(func() { + unauthCommand := redis.NewStatusCmd(ctx, "ACL", "DELUSER", aclSentinelUsername) + + for _, process := range sentinels() { + err := process.Client.Process(ctx, unauthCommand) + Expect(err).NotTo(HaveOccurred()) + } + + _ = client.Close() + _ = sentinel.Close() + }) + + It("should still facilitate operations", func() { + err := client.Set(ctx, "wow", "acl-auth", 0).Err() + Expect(err).NotTo(HaveOccurred()) + + val, err := client.Get(ctx, "wow").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal("acl-auth")) + }) +}) diff --git a/tx.go b/tx.go index 08d381a9d3..8c9d87202a 100644 --- a/tx.go +++ b/tx.go @@ -13,7 +13,8 @@ const TxFailedErr = proto.RedisError("redis: transaction failed") // Tx implements Redis transactions as described in // http://redis.io/topics/transactions. It's NOT safe for concurrent use // by multiple goroutines, because Exec resets list of watched keys. -// If you don't need WATCH it is better to use Pipeline. +// +// If you don't need WATCH, use Pipeline instead. type Tx struct { baseClient cmdable diff --git a/tx_test.go b/tx_test.go index 11e5b0d953..7deb2dfd22 100644 --- a/tx_test.go +++ b/tx_test.go @@ -5,10 +5,10 @@ import ( "strconv" "sync" - "github.com/go-redis/redis/v8" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + + "github.com/go-redis/redis/v8" ) var _ = Describe("Tx", func() { @@ -123,7 +123,7 @@ var _ = Describe("Tx", func() { Expect(num).To(Equal(int64(N))) }) - It("should remove from bad connection", func() { + It("should recover from bad connection", func() { // Put bad connection in the pool. cn, err := client.Pool().Get(context.Background()) Expect(err).NotTo(HaveOccurred()) @@ -134,14 +134,17 @@ var _ = Describe("Tx", func() { do := func() error { err := client.Watch(ctx, func(tx *redis.Tx) error { _, err := tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error { - return pipe.Ping(ctx).Err() + pipe.Ping(ctx) + return nil }) return err }) return err } - // connCheck will automatically remove damaged connections. + err = do() + Expect(err).To(MatchError("bad connection")) + err = do() Expect(err).NotTo(HaveOccurred()) }) diff --git a/universal.go b/universal.go index 1e962ab3be..c89b3e5d74 100644 --- a/universal.go +++ b/universal.go @@ -25,6 +25,7 @@ type UniversalOptions struct { Username string Password string + SentinelUsername string SentinelPassword string MaxRetries int @@ -114,6 +115,7 @@ func (o *UniversalOptions) Failover() *FailoverOptions { DB: o.DB, Username: o.Username, Password: o.Password, + SentinelUsername: o.SentinelUsername, SentinelPassword: o.SentinelPassword, MaxRetries: o.MaxRetries, diff --git a/version.go b/version.go new file mode 100644 index 0000000000..112c9a2da0 --- /dev/null +++ b/version.go @@ -0,0 +1,6 @@ +package redis + +// Version is the current release version. +func Version() string { + return "8.11.5" +} From 997ab5e7e3ddf53837917013a4babbded73e944f Mon Sep 17 00:00:00 2001 From: Monkey Date: Sat, 19 Mar 2022 18:22:12 +0800 Subject: [PATCH 017/621] fix(#1943): xInfoConsumer.Idle should be time.Duration instead of int64 (#2052) Signed-off-by: monkey92t --- command.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/command.go b/command.go index 810dededd4..00af6c1d6e 100644 --- a/command.go +++ b/command.go @@ -1857,7 +1857,7 @@ type XInfoConsumersCmd struct { type XInfoConsumer struct { Name string Pending int64 - Idle int64 + Idle time.Duration } var _ Cmder = (*XInfoConsumersCmd)(nil) @@ -1906,19 +1906,21 @@ func (cmd *XInfoConsumersCmd) readReply(rd *proto.Reader) error { return err } + var idle int64 switch key { case "name": cmd.val[i].Name, err = rd.ReadString() case "pending": cmd.val[i].Pending, err = rd.ReadInt() case "idle": - cmd.val[i].Idle, err = rd.ReadInt() + idle, err = rd.ReadInt() default: return fmt.Errorf("redis: unexpected content %s in XINFO CONSUMERS reply", key) } if err != nil { return err } + cmd.val[i].Idle = time.Duration(idle) * time.Millisecond } } From 6f1a1ac284ea3f683eeb3b06a59969e8424b6376 Mon Sep 17 00:00:00 2001 From: monkey92t Date: Sat, 19 Mar 2022 20:54:27 +0800 Subject: [PATCH 018/621] fix: add XInfoConsumers test Signed-off-by: monkey92t --- command.go | 4 ++-- commands_test.go | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/command.go b/command.go index 00af6c1d6e..f9d8af3678 100644 --- a/command.go +++ b/command.go @@ -1906,21 +1906,21 @@ func (cmd *XInfoConsumersCmd) readReply(rd *proto.Reader) error { return err } - var idle int64 switch key { case "name": cmd.val[i].Name, err = rd.ReadString() case "pending": cmd.val[i].Pending, err = rd.ReadInt() case "idle": + var idle int64 idle, err = rd.ReadInt() + cmd.val[i].Idle = time.Duration(idle) * time.Millisecond default: return fmt.Errorf("redis: unexpected content %s in XINFO CONSUMERS reply", key) } if err != nil { return err } - cmd.val[i].Idle = time.Duration(idle) * time.Millisecond } } diff --git a/commands_test.go b/commands_test.go index 81c1bdb878..e1cceb9fec 100644 --- a/commands_test.go +++ b/commands_test.go @@ -5008,6 +5008,7 @@ var _ = Describe("Commands", func() { res, err := client.XInfoConsumers(ctx, "stream", "group1").Result() Expect(err).NotTo(HaveOccurred()) for i := range res { + Expect(res[i].Idle > 0).To(BeTrue()) res[i].Idle = 0 } Expect(res).To(Equal([]redis.XInfoConsumer{ From f5fbb367e7d9dfd7f391fc535a7387002232fa8a Mon Sep 17 00:00:00 2001 From: monkey92t Date: Sat, 19 Mar 2022 22:04:22 +0800 Subject: [PATCH 019/621] fix: remove test(XInfoConsumer.idle), not a stable return value when tested. Signed-off-by: monkey92t --- commands_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/commands_test.go b/commands_test.go index e1cceb9fec..81c1bdb878 100644 --- a/commands_test.go +++ b/commands_test.go @@ -5008,7 +5008,6 @@ var _ = Describe("Commands", func() { res, err := client.XInfoConsumers(ctx, "stream", "group1").Result() Expect(err).NotTo(HaveOccurred()) for i := range res { - Expect(res[i].Idle > 0).To(BeTrue()) res[i].Idle = 0 } Expect(res).To(Equal([]redis.XInfoConsumer{ From a8a7665ddf8cc657c5226b1826a8ee83dab4b8c1 Mon Sep 17 00:00:00 2001 From: naiqianz Date: Mon, 21 Mar 2022 01:06:47 +0800 Subject: [PATCH 020/621] feat(pool): add check for badConnection * fix: badConn check(#2053) * fix: internalpool test * fix: sentinel test * fix: conncheck ut * fix: remove maxBadConnRetries * fix: add connCheck.deadline check Signed-off-by: monkey92t --- internal/pool/conn_check.go | 49 +++++++++++++++++ internal/pool/conn_check_dummy.go | 9 ++++ internal/pool/conn_check_test.go | 48 +++++++++++++++++ internal/pool/export_test.go | 5 ++ internal/pool/main_test.go | 87 ++++++++++++++++++++++++++++++- internal/pool/pool.go | 4 +- internal/pool/pool_test.go | 3 ++ pool_test.go | 2 +- sentinel_test.go | 2 +- tx_test.go | 3 -- 10 files changed, 204 insertions(+), 8 deletions(-) create mode 100644 internal/pool/conn_check.go create mode 100644 internal/pool/conn_check_dummy.go create mode 100644 internal/pool/conn_check_test.go diff --git a/internal/pool/conn_check.go b/internal/pool/conn_check.go new file mode 100644 index 0000000000..1afdd6fea8 --- /dev/null +++ b/internal/pool/conn_check.go @@ -0,0 +1,49 @@ +// +build linux darwin dragonfly freebsd netbsd openbsd solaris illumos + +package pool + +import ( + "errors" + "io" + "net" + "syscall" + "time" +) + +var errUnexpectedRead = errors.New("unexpected read from socket") + +func connCheck(conn net.Conn) error { + // Reset previous timeout. + _ = conn.SetDeadline(time.Time{}) + + sysConn, ok := conn.(syscall.Conn) + if !ok { + return nil + } + rawConn, err := sysConn.SyscallConn() + if err != nil { + return err + } + + var sysErr error + err = rawConn.Read(func(fd uintptr) bool { + var buf [1]byte + n, err := syscall.Read(int(fd), buf[:]) + switch { + case n == 0 && err == nil: + sysErr = io.EOF + case n > 0: + sysErr = errUnexpectedRead + case err == syscall.EAGAIN || err == syscall.EWOULDBLOCK: + sysErr = nil + default: + sysErr = err + } + return true + }) + if err != nil { + return err + } + + return sysErr +} \ No newline at end of file diff --git a/internal/pool/conn_check_dummy.go b/internal/pool/conn_check_dummy.go new file mode 100644 index 0000000000..e7d6280884 --- /dev/null +++ b/internal/pool/conn_check_dummy.go @@ -0,0 +1,9 @@ +// +build !linux,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!illumos + +package pool + +import "net" + +func connCheck(conn net.Conn) error { + return nil +} \ No newline at end of file diff --git a/internal/pool/conn_check_test.go b/internal/pool/conn_check_test.go new file mode 100644 index 0000000000..6adfc3d035 --- /dev/null +++ b/internal/pool/conn_check_test.go @@ -0,0 +1,48 @@ +//go:build linux || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || illumos +// +build linux darwin dragonfly freebsd netbsd openbsd solaris illumos + +package pool + +import ( + "net" + "net/http/httptest" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("tests conn_check with real conns", func() { + var ts *httptest.Server + var conn net.Conn + var err error + + BeforeEach(func() { + ts = httptest.NewServer(nil) + conn, err = net.DialTimeout(ts.Listener.Addr().Network(), ts.Listener.Addr().String(), time.Second) + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + ts.Close() + }) + + It("good conn check", func() { + Expect(connCheck(conn)).NotTo(HaveOccurred()) + + Expect(conn.Close()).NotTo(HaveOccurred()) + Expect(connCheck(conn)).To(HaveOccurred()) + }) + + It("bad conn check", func() { + Expect(conn.Close()).NotTo(HaveOccurred()) + Expect(connCheck(conn)).To(HaveOccurred()) + }) + + It("check conn deadline", func() { + Expect(conn.SetDeadline(time.Now())).NotTo(HaveOccurred()) + time.Sleep(time.Millisecond * 10) + Expect(connCheck(conn)).NotTo(HaveOccurred()) + Expect(conn.Close()).NotTo(HaveOccurred()) + }) +}) diff --git a/internal/pool/export_test.go b/internal/pool/export_test.go index 75dd4ad61c..18c6bbd597 100644 --- a/internal/pool/export_test.go +++ b/internal/pool/export_test.go @@ -1,9 +1,14 @@ package pool import ( + "net" "time" ) func (cn *Conn) SetCreatedAt(tm time.Time) { cn.createdAt = tm } + +func (cn *Conn) NetConn() net.Conn { + return cn.netConn +} \ No newline at end of file diff --git a/internal/pool/main_test.go b/internal/pool/main_test.go index 2365dbc645..c54a38d514 100644 --- a/internal/pool/main_test.go +++ b/internal/pool/main_test.go @@ -2,9 +2,12 @@ package pool_test import ( "context" + "fmt" "net" "sync" + "syscall" "testing" + "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -32,5 +35,87 @@ func perform(n int, cbs ...func(int)) { } func dummyDialer(context.Context) (net.Conn, error) { - return &net.TCPConn{}, nil + // return &net.TCPConn{}, nil + return newDummyConn(), nil +} + +func newDummyConn() net.Conn { + return &dummyConn{ + rawConn: &dummyRawConn{}, + } +} + +var _ net.Conn = (*dummyConn)(nil) +var _ syscall.Conn = (*dummyConn)(nil) + +type dummyConn struct { + rawConn *dummyRawConn +} + +func (d *dummyConn) SyscallConn() (syscall.RawConn, error) { + return d.rawConn, nil +} + +var errDummy = fmt.Errorf("dummyConn err") + +func (d *dummyConn) Read(b []byte) (n int, err error) { + return 0, errDummy +} + +func (d *dummyConn) Write(b []byte) (n int, err error) { + return 0, errDummy +} + +func (d *dummyConn) Close() error { + d.rawConn.Close() + return nil +} + +func (d *dummyConn) LocalAddr() net.Addr { + return &net.TCPAddr{} +} + +func (d *dummyConn) RemoteAddr() net.Addr { + return &net.TCPAddr{} +} + +func (d *dummyConn) SetDeadline(t time.Time) error { + return nil +} + +func (d *dummyConn) SetReadDeadline(t time.Time) error { + return nil +} + +func (d *dummyConn) SetWriteDeadline(t time.Time) error { + return nil +} + +var _ syscall.RawConn = (*dummyRawConn)(nil) + +type dummyRawConn struct { + closed bool + mux sync.Mutex +} + +func (d *dummyRawConn) Control(f func(fd uintptr)) error { + return nil +} + +func (d *dummyRawConn) Read(f func(fd uintptr) (done bool)) error { + d.mux.Lock() + defer d.mux.Unlock() + if d.closed { + return fmt.Errorf("dummyRawConn closed") + } + return nil +} + +func (d *dummyRawConn) Write(f func(fd uintptr) (done bool)) error { + return nil +} +func (d *dummyRawConn) Close() { + d.mux.Lock() + d.closed = true + d.mux.Unlock() } diff --git a/internal/pool/pool.go b/internal/pool/pool.go index 44a4e779df..3a6ecb27fd 100644 --- a/internal/pool/pool.go +++ b/internal/pool/pool.go @@ -542,7 +542,7 @@ func (p *ConnPool) reapStaleConn() *Conn { func (p *ConnPool) isStaleConn(cn *Conn) bool { if p.opt.IdleTimeout == 0 && p.opt.MaxConnAge == 0 { - return false + return connCheck(cn.netConn) != nil } now := time.Now() @@ -553,5 +553,5 @@ func (p *ConnPool) isStaleConn(cn *Conn) bool { return true } - return false + return connCheck(cn.netConn) != nil } diff --git a/internal/pool/pool_test.go b/internal/pool/pool_test.go index 423a783cbe..d0fbfe19c7 100644 --- a/internal/pool/pool_test.go +++ b/internal/pool/pool_test.go @@ -323,6 +323,8 @@ var _ = Describe("conns reaper", func() { cn.SetUsedAt(time.Now().Add(-2 * idleTimeout)) case "aged": cn.SetCreatedAt(time.Now().Add(-2 * maxAge)) + case "connCheck": + _ = cn.Close() } conns = append(conns, cn) staleConns = append(staleConns, cn) @@ -409,6 +411,7 @@ var _ = Describe("conns reaper", func() { assert("idle") assert("aged") + assert("connCheck") }) var _ = Describe("race", func() { diff --git a/pool_test.go b/pool_test.go index e297b010d6..56d290cef1 100644 --- a/pool_test.go +++ b/pool_test.go @@ -87,7 +87,7 @@ var _ = Describe("pool", func() { client.Pool().Put(ctx, cn) err = client.Ping(ctx).Err() - Expect(err).To(MatchError("bad connection")) + Expect(err).NotTo(HaveOccurred()) val, err := client.Ping(ctx).Result() Expect(err).NotTo(HaveOccurred()) diff --git a/sentinel_test.go b/sentinel_test.go index cc56cbabac..dae28feaa5 100644 --- a/sentinel_test.go +++ b/sentinel_test.go @@ -192,7 +192,7 @@ var _ = Describe("NewFailoverClusterClient", func() { err = master.Shutdown(ctx).Err() Expect(err).NotTo(HaveOccurred()) Eventually(func() error { - return sentinelMaster.Ping(ctx).Err() + return master.Ping(ctx).Err() }, "15s", "100ms").Should(HaveOccurred()) // Check that client picked up new master. diff --git a/tx_test.go b/tx_test.go index 7deb2dfd22..030a56cc6b 100644 --- a/tx_test.go +++ b/tx_test.go @@ -142,9 +142,6 @@ var _ = Describe("Tx", func() { return err } - err = do() - Expect(err).To(MatchError("bad connection")) - err = do() Expect(err).NotTo(HaveOccurred()) }) From e83e61f0bf22e59362201e85bdf0e98f6c140532 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 01:27:39 +0000 Subject: [PATCH 021/621] chore(deps): bump actions/setup-go from 2 to 3 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2 to 3. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 73c664096a..8369e141b0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Set up ${{ matrix.go-version }} - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: ${{ matrix.go-version }} From e685ead9efe67931f5b43e7559fd6ca1eb18f6ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 01:27:44 +0000 Subject: [PATCH 022/621] chore(deps): bump golangci/golangci-lint-action from 2 to 3 Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 2 to 3. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/v2...v3) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/golangci-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 28c16c5834..7f000466e6 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -16,4 +16,4 @@ jobs: steps: - uses: actions/checkout@v3 - name: golangci-lint - uses: golangci/golangci-lint-action@v2 + uses: golangci/golangci-lint-action@v3 From fc61bffa4915983f6e264e3fcb5b121ff837e9e8 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Wed, 13 Apr 2022 15:53:17 +0300 Subject: [PATCH 023/621] chore: fix links --- example/hll/README.md | 3 ++- example/otel/README.md | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/example/hll/README.md b/example/hll/README.md index cd78d7f1e0..725780ba5b 100644 --- a/example/hll/README.md +++ b/example/hll/README.md @@ -6,4 +6,5 @@ To run this example: go run . ``` -See [Using HyperLogLog command with go-redis](https://redis.uptrace.dev/guide/hll.html) for details. +See [Using HyperLogLog command with go-redis](https://redis.uptrace.dev/guide/go-redis-hll.html) for +details. diff --git a/example/otel/README.md b/example/otel/README.md index 567a882779..e0451ecbcc 100644 --- a/example/otel/README.md +++ b/example/otel/README.md @@ -1,6 +1,8 @@ # Example for go-redis OpenTelemetry instrumentation -See [Monitoring performance and errors](https://redis.uptrace.dev/guide/tracing.html) for details. +See +[Redis Monitoring Performance and Errors](https://redis.uptrace.dev/guide/redis-performance-monitoring.html) +for details. This example requires Redis Server on port `:6379`. You can start Redis Server using Docker: From 354913edcac712543a10097bc24241c5ab4c25ff Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Wed, 13 Apr 2022 16:01:35 +0300 Subject: [PATCH 024/621] chore: update readme links --- README.md | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index fad843fb6a..663f23453c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ - [Chat](https://discord.gg/rWtp5Aj) - [Reference](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc) - [Examples](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#pkg-examples) -- [RealWorld example app](https://github.com/uptrace/go-treemux-realworld-example-app) ## Ecosystem @@ -30,19 +29,13 @@ - Redis 3 commands except QUIT, MONITOR, and SYNC. - Automatic connection pooling with - [circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker_design_pattern) support. -- [Pub/Sub](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#PubSub). -- [Transactions](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client-TxPipeline). -- [Pipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client.Pipeline) and - [TxPipeline](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-Client.TxPipeline). -- [Scripting](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Script). -- [Timeouts](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options). -- [Redis Sentinel](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewFailoverClient). -- [Redis Cluster](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewClusterClient). -- [Cluster of Redis Servers](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-NewClusterClient-ManualSetup) - without using cluster mode and Redis Sentinel. -- [Ring](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#NewRing). -- [Instrumentation](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#example-package-Instrumentation). +- [Pub/Sub](https://redis.uptrace.dev/guide/go-redis-pubsub.html). +- [Pipelines and transactions](https://redis.uptrace.dev/guide/go-redis-pipelines.html). +- [Scripting](https://redis.uptrace.dev/guide/lua-scripting.html). +- [Redis Sentinel](https://redis.uptrace.dev/guide/go-redis-sentinel.html). +- [Redis Cluster](https://redis.uptrace.dev/guide/go-redis-cluster.html). +- [Redis Ring](https://redis.uptrace.dev/guide/ring.html). +- [Redis Performance Monitoring](https://redis.uptrace.dev/guide/redis-performance-monitoring.html). ## Installation @@ -143,7 +136,7 @@ go-redis will start a redis-server and run the test cases. The paths of redis-server bin file and redis config file are defined in `main_test.go`: -``` +```go var ( redisServerBin, _ = filepath.Abs(filepath.Join("testdata", "redis", "src", "redis-server")) redisServerConf, _ = filepath.Abs(filepath.Join("testdata", "redis", "redis.conf")) @@ -153,14 +146,14 @@ var ( For local testing, you can change the variables to refer to your local files, or create a soft link to the corresponding folder for redis-server and copy the config file to `testdata/redis/`: -``` +```shell ln -s /usr/bin/redis-server ./go-redis/testdata/redis/src cp ./go-redis/testdata/redis.conf ./go-redis/testdata/redis/ ``` Lastly, run: -``` +```shell go test ``` From 4c8b4d1619159a90d9297d5981cbc678e32308ac Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Thu, 14 Apr 2022 17:55:34 +0300 Subject: [PATCH 025/621] chore: mention kvrocks --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 663f23453c..a1431064f6 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,9 @@ - [Redis Cache](https://github.com/go-redis/cache) - [Rate limiting](https://github.com/go-redis/redis_rate) +This client also works with [kvrocks](https://github.com/KvrocksLabs/kvrocks), a distributed key +value NoSQL database that uses RocksDB as storage engine and is compatible with Redis protocol. + ## Features - Redis 3 commands except QUIT, MONITOR, and SYNC. From 8ed377346750a7e4c70a697eff4720f049a23975 Mon Sep 17 00:00:00 2001 From: neilnaveen <42328488+neilnaveen@users.noreply.github.com> Date: Wed, 20 Apr 2022 15:48:57 +0000 Subject: [PATCH 026/621] chore: Set permissions for GitHub actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restrict the GitHub token permissions only to the required ones; this way, even if the attackers will succeed in compromising your workflow, they won’t be able to do much. - Included permissions for the action. https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/) Signed-off-by: neilnaveen <42328488+neilnaveen@users.noreply.github.com> --- .github/workflows/build.yml | 3 +++ .github/workflows/golangci-lint.yml | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 73c664096a..a7c662acab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [master] +permissions: + contents: read + jobs: build: name: build diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 28c16c5834..6f0cf28ee3 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -9,8 +9,14 @@ on: - main pull_request: +permissions: + contents: read + jobs: golangci: + permissions: + contents: read # for actions/checkout to fetch code + pull-requests: read # for golangci/golangci-lint-action to fetch pull requests name: lint runs-on: ubuntu-latest steps: From 07e15d2876ccc88afcd0f344a3eed6a050ff1921 Mon Sep 17 00:00:00 2001 From: Bogus Jung Date: Thu, 28 Apr 2022 20:32:20 +0900 Subject: [PATCH 027/621] fix: tags for structToMap "json" -> "key" --- commands.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/commands.go b/commands.go index 5ee66fab85..ff096c6ecc 100644 --- a/commands.go +++ b/commands.go @@ -91,7 +91,7 @@ func structToMap(items interface{}) map[string]interface{} { v = v.Elem() } for i := 0; i < v.NumField(); i++ { - tag := v.Field(i).Tag.Get("json") + tag := v.Field(i).Tag.Get("key") if tag != "" && v.Field(i).Type.Kind() != reflect.Struct { field := reflectValue.Field(i).Interface() @@ -1285,7 +1285,10 @@ func (c cmdable) HMGet(ctx context.Context, key string, fields ...string) *Slice // - HSet("myhash", "key1", "value1", "key2", "value2") // - HSet("myhash", []string{"key1", "value1", "key2", "value2"}) // - HSet("myhash", map[string]interface{}{"key1": "value1", "key2": "value2"}) -// - HSet("myhash", struct{Key1: "value1"; Key2: "value2"}) +// +// Playing struct With "key" tag +// - type MyHash struct { Key1 string `key:"key1"`; Key2 int `key:"key2"` } +// - HSet("myhash", MyHash{"value1", "value2"}) // // Note that it requires Redis v4 for multiple field/value pairs support. func (c cmdable) HSet(ctx context.Context, key string, values ...interface{}) *IntCmd { From 1fdcbf86bbb390e4e689a35a391a4a4b3917216d Mon Sep 17 00:00:00 2001 From: Bogus Jung Date: Thu, 28 Apr 2022 20:32:58 +0900 Subject: [PATCH 028/621] fix: test code --- example_test.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/example_test.go b/example_test.go index e696fdfe79..8b32e79e16 100644 --- a/example_test.go +++ b/example_test.go @@ -198,13 +198,15 @@ func ExampleClient_SetEX() { } func ExampleClient_HSet() { - type Items struct { - Key1 string `json:"key1"` - Key2 string `json:"key2"` + // Set "key" tag for hash key + type ExampleUser struct { + Name string `key:"name"` + Age int `key:"age"` } - items := Items{"field1", "field2"} - - err := rdb.HSet(ctx, "key", items).Err() + + items := ExampleUser{"jane", 22} + + err := rdb.HSet(ctx, "user:1", items).Err() if err != nil { panic(err) } From a4da15b8ad7755f5b4058d7eac50c832c4e799c4 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Tue, 3 May 2022 17:48:11 +0300 Subject: [PATCH 029/621] chore: add sponsors --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index a1431064f6..90a74e805c 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,19 @@ value NoSQL database that uses RocksDB as storage engine and is compatible with - [Redis Ring](https://redis.uptrace.dev/guide/ring.html). - [Redis Performance Monitoring](https://redis.uptrace.dev/guide/redis-performance-monitoring.html). +## Sponsors + +### Upstash: Serverless Database for Redis + +Upstash + +Upstash is a Serverless Database with Redis/REST API and durable storage. It is the perfect database +for your applications thanks to its per request pricing and low latency data. + +[Start for free in 30 seconds!](https://upstash.com/?utm_source=goredis) + +
+ ## Installation go-redis supports 2 last Go versions and requires a Go version with From 2465baaab55d74ec9d5e42a971b2bf5dba3a6b29 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Tue, 3 May 2022 17:50:48 +0300 Subject: [PATCH 030/621] chore: move sponsors up --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 90a74e805c..d218a52ba3 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,19 @@ > [distributed tracing tool](https://get.uptrace.dev/compare/distributed-tracing-tools.html) powered > by OpenTelemetry and ClickHouse. Give it a star as well! +## Sponsors + +### Upstash: Serverless Database for Redis + +Upstash + +Upstash is a Serverless Database with Redis/REST API and durable storage. It is the perfect database +for your applications thanks to its per request pricing and low latency data. + +[Start for free in 30 seconds!](https://upstash.com/?utm_source=goredis) + +
+ ## Resources - [Documentation](https://redis.uptrace.dev) @@ -40,19 +53,6 @@ value NoSQL database that uses RocksDB as storage engine and is compatible with - [Redis Ring](https://redis.uptrace.dev/guide/ring.html). - [Redis Performance Monitoring](https://redis.uptrace.dev/guide/redis-performance-monitoring.html). -## Sponsors - -### Upstash: Serverless Database for Redis - -Upstash - -Upstash is a Serverless Database with Redis/REST API and durable storage. It is the perfect database -for your applications thanks to its per request pricing and low latency data. - -[Start for free in 30 seconds!](https://upstash.com/?utm_source=goredis) - -
- ## Installation go-redis supports 2 last Go versions and requires a Go version with From 56a3dbc7b656525eb88e0735e239d56e04a23bee Mon Sep 17 00:00:00 2001 From: janbar Date: Sat, 4 Jun 2022 15:26:04 +0800 Subject: [PATCH 031/621] feat: provide a username and password callback method, so that the plaintext username and password will not be stored in the memory, and the username and password will only be generated once when the CredentialsProvider is called. After the method is executed, the username and password strings on the stack will be released. (#2097) Co-authored-by: janbar --- options.go | 3 +++ redis.go | 15 ++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/options.go b/options.go index a4abe32c3a..e74f599abb 100644 --- a/options.go +++ b/options.go @@ -51,6 +51,9 @@ type Options struct { // or the User Password when connecting to a Redis 6.0 instance, or greater, // that is using the Redis ACL system. Password string + // CredentialsProvider allows the username and password to be updated + // before reconnecting. It should return the current username and password. + CredentialsProvider func() (username string, password string) // Database to be selected after connecting to the server. DB int diff --git a/redis.go b/redis.go index bcf8a2a94b..fa57dee376 100644 --- a/redis.go +++ b/redis.go @@ -217,7 +217,12 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { } cn.Inited = true - if c.opt.Password == "" && + username, password := c.opt.Username, c.opt.Password + if c.opt.CredentialsProvider != nil { + username, password = c.opt.CredentialsProvider() + } + + if password == "" && c.opt.DB == 0 && !c.opt.readOnly && c.opt.OnConnect == nil { @@ -228,11 +233,11 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { conn := newConn(ctx, c.opt, connPool) _, err := conn.Pipelined(ctx, func(pipe Pipeliner) error { - if c.opt.Password != "" { - if c.opt.Username != "" { - pipe.AuthACL(ctx, c.opt.Username, c.opt.Password) + if password != "" { + if username != "" { + pipe.AuthACL(ctx, username, password) } else { - pipe.Auth(ctx, c.opt.Password) + pipe.Auth(ctx, password) } } From 1980be0f9f2be1e60fb4b6475820e4bbd9110708 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 10:50:58 +0300 Subject: [PATCH 032/621] chore: fix golangci-lint --- error.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/error.go b/error.go index 521594bbd0..a6567eff12 100644 --- a/error.go +++ b/error.go @@ -91,7 +91,7 @@ func isBadConn(err error, allowTimeout bool, addr string) bool { if allowTimeout { if netErr, ok := err.(net.Error); ok && netErr.Timeout() { - return !netErr.Temporary() + return false } } From 52af8ba8529328947f70eb5573ddff3474b4fc55 Mon Sep 17 00:00:00 2001 From: "renzheng.wang" Date: Sat, 4 Jun 2022 18:24:32 +0800 Subject: [PATCH 033/621] update cluster slots reply checking logic for Redis 7 (#2108) fix: update cluster slots reply checking logic for redis 7 --- command.go | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/command.go b/command.go index 4bb12a85be..a97f9e9737 100644 --- a/command.go +++ b/command.go @@ -2628,8 +2628,9 @@ func (cmd *ScanCmd) Iterator() *ScanIterator { //------------------------------------------------------------------------------ type ClusterNode struct { - ID string - Addr string + ID string + Addr string + NetworkingMetadata map[string]string } type ClusterSlot struct { @@ -2700,8 +2701,8 @@ func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error { if err != nil { return nil, err } - if n != 2 && n != 3 { - err := fmt.Errorf("got %d elements in cluster info address, expected 2 or 3", n) + if n < 2 || n > 4 { + err := fmt.Errorf("got %d elements in cluster info address, shoud be between 2 and 4", n) return nil, err } @@ -2717,13 +2718,36 @@ func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error { nodes[j].Addr = net.JoinHostPort(ip, port) - if n == 3 { + if n >= 3 { id, err := rd.ReadString() if err != nil { return nil, err } nodes[j].ID = id } + if n == 4 { + networkingMetadata := make(map[string]string) + metadataLength, err := rd.ReadArrayLen() + if err != nil { + return nil, err + } + if metadataLength%2 != 0 { + err := fmt.Errorf("the array length of metadata must be a even number, current: %d", metadataLength) + return nil, err + } + for i := 0; i < metadataLength; i = i + 2 { + key, err := rd.ReadString() + if err != nil { + return nil, err + } + value, err := rd.ReadString() + if err != nil { + return nil, err + } + networkingMetadata[key] = value + } + nodes[j].NetworkingMetadata = networkingMetadata + } } cmd.val[i] = ClusterSlot{ From a15a89ea5876f83e3a8c77f442a26467fdd8fa47 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 14:52:46 +0300 Subject: [PATCH 034/621] chore: fix build --- internal/pool/pool.go | 4 ++-- main_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/pool/pool.go b/internal/pool/pool.go index 44a4e779df..3a6ecb27fd 100644 --- a/internal/pool/pool.go +++ b/internal/pool/pool.go @@ -542,7 +542,7 @@ func (p *ConnPool) reapStaleConn() *Conn { func (p *ConnPool) isStaleConn(cn *Conn) bool { if p.opt.IdleTimeout == 0 && p.opt.MaxConnAge == 0 { - return false + return connCheck(cn.netConn) != nil } now := time.Now() @@ -553,5 +553,5 @@ func (p *ConnPool) isStaleConn(cn *Conn) bool { return true } - return false + return connCheck(cn.netConn) != nil } diff --git a/main_test.go b/main_test.go index 5414310e71..5529112e95 100644 --- a/main_test.go +++ b/main_test.go @@ -324,7 +324,7 @@ func startRedis(port string, args ...string) (*redisProcess, error) { p := &redisProcess{process, client} registerProcess(port, p) - return p, err + return p, nil } func startSentinel(port, masterName, masterPort string) (*redisProcess, error) { From 91171f5e19a261dc4cfbf8706626d461b6ba03e4 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 15:02:53 +0300 Subject: [PATCH 035/621] feat: add ClientUnpause --- command.go | 36 +++++++++++++-- commands.go | 7 +++ internal/pool/main_test.go | 89 +++++++++++++++++++++++++++++++++++++- 3 files changed, 128 insertions(+), 4 deletions(-) diff --git a/command.go b/command.go index a6beea664e..1e5c11dc5e 100644 --- a/command.go +++ b/command.go @@ -2649,13 +2649,14 @@ func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error { // subtract start and end. nodes := make([]ClusterNode, n-2) + for j := 0; j < len(nodes); j++ { nn, err := rd.ReadArrayLen() if err != nil { return err } - if nn != 2 && nn != 3 { - return fmt.Errorf("got %d elements in cluster info address, expected 2 or 3", nn) + if nn < 2 || nn > 4 { + return fmt.Errorf("got %d elements in cluster info address, expected 2, 3, or 4", n) } ip, err := rd.ReadString() @@ -2670,14 +2671,43 @@ func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error { nodes[j].Addr = net.JoinHostPort(ip, port) - if nn == 3 { + if nn >= 3 { id, err := rd.ReadString() if err != nil { return err } nodes[j].ID = id } + + if nn >= 4 { + networkingMetadata := make(map[string]string) + + metadataLength, err := rd.ReadArrayLen() + if err != nil { + return err + } + + if metadataLength%2 != 0 { + return fmt.Errorf( + "got %d elements in metadata, expected an even number", metadataLength) + } + + for i := 0; i < metadataLength; i += 2 { + key, err := rd.ReadString() + if err != nil { + return err + } + value, err := rd.ReadString() + if err != nil { + return err + } + networkingMetadata[key] = value + } + + nodes[j].NetworkingMetadata = networkingMetadata + } } + cmd.val[i] = ClusterSlot{ Start: int(start), End: int(end), diff --git a/commands.go b/commands.go index eb0757d17c..60997a8f64 100644 --- a/commands.go +++ b/commands.go @@ -310,6 +310,7 @@ type Cmdable interface { ClientKillByFilter(ctx context.Context, keys ...string) *IntCmd ClientList(ctx context.Context) *StringCmd ClientPause(ctx context.Context, dur time.Duration) *BoolCmd + ClientUnpause(ctx context.Context) *BoolCmd ClientID(ctx context.Context) *IntCmd ClientUnblock(ctx context.Context, id int64) *IntCmd ClientUnblockWithError(ctx context.Context, id int64) *IntCmd @@ -2818,6 +2819,12 @@ func (c cmdable) ClientPause(ctx context.Context, dur time.Duration) *BoolCmd { return cmd } +func (c cmdable) ClientUnpause(ctx context.Context) *BoolCmd { + cmd := NewBoolCmd(ctx, "client", "unpause") + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) ClientID(ctx context.Context) *IntCmd { cmd := NewIntCmd(ctx, "client", "id") _ = c(ctx, cmd) diff --git a/internal/pool/main_test.go b/internal/pool/main_test.go index 2365dbc645..8ad167471c 100644 --- a/internal/pool/main_test.go +++ b/internal/pool/main_test.go @@ -2,9 +2,12 @@ package pool_test import ( "context" + "fmt" "net" "sync" + "syscall" "testing" + "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -32,5 +35,89 @@ func perform(n int, cbs ...func(int)) { } func dummyDialer(context.Context) (net.Conn, error) { - return &net.TCPConn{}, nil + return newDummyConn(), nil +} + +func newDummyConn() net.Conn { + return &dummyConn{ + rawConn: new(dummyRawConn), + } +} + +var ( + _ net.Conn = (*dummyConn)(nil) + _ syscall.Conn = (*dummyConn)(nil) +) + +type dummyConn struct { + rawConn *dummyRawConn +} + +func (d *dummyConn) SyscallConn() (syscall.RawConn, error) { + return d.rawConn, nil +} + +var errDummy = fmt.Errorf("dummyConn err") + +func (d *dummyConn) Read(b []byte) (n int, err error) { + return 0, errDummy +} + +func (d *dummyConn) Write(b []byte) (n int, err error) { + return 0, errDummy +} + +func (d *dummyConn) Close() error { + d.rawConn.Close() + return nil +} + +func (d *dummyConn) LocalAddr() net.Addr { + return &net.TCPAddr{} +} + +func (d *dummyConn) RemoteAddr() net.Addr { + return &net.TCPAddr{} +} + +func (d *dummyConn) SetDeadline(t time.Time) error { + return nil +} + +func (d *dummyConn) SetReadDeadline(t time.Time) error { + return nil +} + +func (d *dummyConn) SetWriteDeadline(t time.Time) error { + return nil +} + +var _ syscall.RawConn = (*dummyRawConn)(nil) + +type dummyRawConn struct { + mu sync.Mutex + closed bool +} + +func (d *dummyRawConn) Control(f func(fd uintptr)) error { + return nil +} + +func (d *dummyRawConn) Read(f func(fd uintptr) (done bool)) error { + d.mu.Lock() + defer d.mu.Unlock() + if d.closed { + return fmt.Errorf("dummyRawConn closed") + } + return nil +} + +func (d *dummyRawConn) Write(f func(fd uintptr) (done bool)) error { + return nil +} + +func (d *dummyRawConn) Close() { + d.mu.Lock() + d.closed = true + d.mu.Unlock() } From 3a722be81180e4d2a9cf0a29dc9a1ee1421f5859 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 15:15:43 +0300 Subject: [PATCH 036/621] fix: fix tests --- Makefile | 5 ++--- extra/redisotel/redisotel_test.go | 8 +++++--- internal/pool/conn_check.go | 3 ++- internal/pool/conn_check_dummy.go | 3 ++- pool_test.go | 7 ++++--- sentinel_test.go | 4 ++-- tx_test.go | 3 --- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index a4cfe0576e..8dcddb24df 100644 --- a/Makefile +++ b/Makefile @@ -26,10 +26,9 @@ fmt: goimports -w -local github.com/go-redis/redis ./ go_mod_tidy: - go get -u && go mod tidy set -e; for dir in $(PACKAGE_DIRS); do \ echo "go mod tidy in $${dir}"; \ (cd "$${dir}" && \ - go get -u && \ - go mod tidy); \ + go get -u ./... && \ + go mod tidy -compat=1.17); \ done diff --git a/extra/redisotel/redisotel_test.go b/extra/redisotel/redisotel_test.go index 68aacc4a08..883dcf1734 100644 --- a/extra/redisotel/redisotel_test.go +++ b/extra/redisotel/redisotel_test.go @@ -2,14 +2,16 @@ package redisotel_test import ( "context" - semconv "go.opentelemetry.io/otel/semconv/v1.7.0" "testing" - "github.com/go-redis/redis/extra/redisotel/v8" - "github.com/go-redis/redis/v8" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + "go.opentelemetry.io/otel" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" + + "github.com/go-redis/redis/extra/redisotel/v8" + "github.com/go-redis/redis/v8" ) func TestNew(t *testing.T) { diff --git a/internal/pool/conn_check.go b/internal/pool/conn_check.go index 1afdd6fea8..74680e4b39 100644 --- a/internal/pool/conn_check.go +++ b/internal/pool/conn_check.go @@ -1,3 +1,4 @@ +//go:build linux || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || illumos // +build linux darwin dragonfly freebsd netbsd openbsd solaris illumos package pool @@ -46,4 +47,4 @@ func connCheck(conn net.Conn) error { } return sysErr -} \ No newline at end of file +} diff --git a/internal/pool/conn_check_dummy.go b/internal/pool/conn_check_dummy.go index e7d6280884..9408446b5c 100644 --- a/internal/pool/conn_check_dummy.go +++ b/internal/pool/conn_check_dummy.go @@ -1,3 +1,4 @@ +//go:build !linux && !darwin && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !illumos // +build !linux,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!illumos package pool @@ -6,4 +7,4 @@ import "net" func connCheck(conn net.Conn) error { return nil -} \ No newline at end of file +} diff --git a/pool_test.go b/pool_test.go index e297b010d6..7be2ced705 100644 --- a/pool_test.go +++ b/pool_test.go @@ -86,13 +86,14 @@ var _ = Describe("pool", func() { cn.SetNetConn(&badConn{}) client.Pool().Put(ctx, cn) - err = client.Ping(ctx).Err() - Expect(err).To(MatchError("bad connection")) - val, err := client.Ping(ctx).Result() Expect(err).NotTo(HaveOccurred()) Expect(val).To(Equal("PONG")) + val, err = client.Ping(ctx).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(Equal("PONG")) + pool := client.Pool() Expect(pool.Len()).To(Equal(1)) Expect(pool.IdleLen()).To(Equal(1)) diff --git a/sentinel_test.go b/sentinel_test.go index cc56cbabac..d0fa9c959a 100644 --- a/sentinel_test.go +++ b/sentinel_test.go @@ -192,7 +192,7 @@ var _ = Describe("NewFailoverClusterClient", func() { err = master.Shutdown(ctx).Err() Expect(err).NotTo(HaveOccurred()) Eventually(func() error { - return sentinelMaster.Ping(ctx).Err() + return master.Ping(ctx).Err() }, "15s", "100ms").Should(HaveOccurred()) // Check that client picked up new master. @@ -223,7 +223,7 @@ var _ = Describe("SentinelAclAuth", func() { var client *redis.Client var sentinel *redis.SentinelClient - var sentinels = func() []*redisProcess { + sentinels := func() []*redisProcess { return []*redisProcess{sentinel1, sentinel2, sentinel3} } diff --git a/tx_test.go b/tx_test.go index 7deb2dfd22..030a56cc6b 100644 --- a/tx_test.go +++ b/tx_test.go @@ -142,9 +142,6 @@ var _ = Describe("Tx", func() { return err } - err = do() - Expect(err).To(MatchError("bad connection")) - err = do() Expect(err).NotTo(HaveOccurred()) }) From b0bb514059249e01ed7328c9094e5b8a439dfb12 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 16:07:28 +0300 Subject: [PATCH 037/621] fix: update COMMAND parser for Redis 7 --- bench_decode_test.go | 4 ++-- command.go | 25 +++++++++++++++++++++---- go.mod | 1 + go.sum | 1 + internal/proto/reader.go | 24 ++++++++++++------------ redis.go | 12 +++--------- 6 files changed, 40 insertions(+), 27 deletions(-) diff --git a/bench_decode_test.go b/bench_decode_test.go index b07ad4edff..753130e28f 100644 --- a/bench_decode_test.go +++ b/bench_decode_test.go @@ -41,7 +41,7 @@ func NewClusterClientStub(resp []byte) *ClientStub { client := NewClusterClient(&ClusterOptions{ PoolSize: 128, - Addrs: []string{"127.0.0.1:6379"}, + Addrs: []string{":6379"}, Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) { return stub.stubConn(initHello), nil }, @@ -118,7 +118,7 @@ func BenchmarkDecode(b *testing.B) { } benchmarks := []Benchmark{ - {"single", NewClientStub}, + {"server", NewClientStub}, {"cluster", NewClusterClientStub}, } diff --git a/command.go b/command.go index 1e5c11dc5e..1f4d646fac 100644 --- a/command.go +++ b/command.go @@ -83,7 +83,7 @@ func cmdFirstKeyPos(cmd Cmder, info *CommandInfo) int { if info != nil { return int(info.FirstKeyPos) } - return 0 + return 1 } func cmdString(cmd Cmder, val interface{}) string { @@ -3166,6 +3166,7 @@ func (cmd *CommandsInfoCmd) String() string { func (cmd *CommandsInfoCmd) readReply(rd *proto.Reader) error { const numArgRedis5 = 6 const numArgRedis6 = 7 + const numArgRedis7 = 10 n, err := rd.ReadArrayLen() if err != nil { @@ -3178,8 +3179,12 @@ func (cmd *CommandsInfoCmd) readReply(rd *proto.Reader) error { if err != nil { return err } - if nn != numArgRedis5 && nn != numArgRedis6 { - return fmt.Errorf("redis: got %d elements in COMMAND reply, wanted 6/7", nn) + + switch nn { + case numArgRedis5, numArgRedis6, numArgRedis7: + // ok + default: + return fmt.Errorf("redis: got %d elements in COMMAND reply, wanted 6/7/10", nn) } cmdInfo := &CommandInfo{} @@ -3230,7 +3235,7 @@ func (cmd *CommandsInfoCmd) readReply(rd *proto.Reader) error { } cmdInfo.StepCount = int8(stepCount) - if nn == numArgRedis6 { + if nn >= numArgRedis6 { aclFlagLen, err := rd.ReadArrayLen() if err != nil { return err @@ -3248,6 +3253,18 @@ func (cmd *CommandsInfoCmd) readReply(rd *proto.Reader) error { } } + if nn >= numArgRedis7 { + if err := rd.DiscardNext(); err != nil { + return err + } + if err := rd.DiscardNext(); err != nil { + return err + } + if err := rd.DiscardNext(); err != nil { + return err + } + } + cmd.val[cmdInfo.Name] = cmdInfo } diff --git a/go.mod b/go.mod index 36eb801071..fdf1076b02 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.17 require ( github.com/cespare/xxhash/v2 v2.1.2 + github.com/davecgh/go-spew v1.1.1 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.19.0 diff --git a/go.sum b/go.sum index dfa31aac45..53adb1790f 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,7 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= diff --git a/internal/proto/reader.go b/internal/proto/reader.go index 3ceedca93f..b330f5944b 100644 --- a/internal/proto/reader.go +++ b/internal/proto/reader.go @@ -124,7 +124,7 @@ func (r *Reader) ReadLine() ([]byte, error) { return line, nil } -// readLine that returns an error if: +// readLine returns an error if: // - there is a pending read error; // - or line does not end with \r\n. func (r *Reader) readLine() ([]byte, error) { @@ -403,7 +403,7 @@ func (r *Reader) ReadArrayLen() (int, error) { case RespArray, RespSet, RespPush: return replyLen(line) default: - return 0, fmt.Errorf("redis: can't parse array(array/set/push) reply: %.100q", line) + return 0, fmt.Errorf("redis: can't parse array/set/push reply: %.100q", line) } } @@ -446,6 +446,15 @@ func (r *Reader) ReadMapLen() (int, error) { } } +// DiscardNext read and discard the data represented by the next line. +func (r *Reader) DiscardNext() error { + line, err := r.readLine() + if err != nil { + return err + } + return r.Discard(line) +} + // Discard the data represented by line. func (r *Reader) Discard(line []byte) (err error) { if len(line) == 0 { @@ -486,15 +495,6 @@ func (r *Reader) Discard(line []byte) (err error) { return fmt.Errorf("redis: can't parse %.100q", line) } -// DiscardNext read and discard the data represented by the next line. -func (r *Reader) DiscardNext() error { - line, err := r.readLine() - if err != nil { - return err - } - return r.Discard(line) -} - func replyLen(line []byte) (n int, err error) { n, err = util.Atoi(line[1:]) if err != nil { @@ -515,7 +515,7 @@ func replyLen(line []byte) (n int, err error) { return n, nil } -// IsNilReply detect redis.Nil of RESP2. +// IsNilReply detects redis.Nil of RESP2. func IsNilReply(line []byte) bool { return len(line) == 3 && (line[0] == RespString || line[0] == RespArray) && diff --git a/redis.go b/redis.go index e5d0eb1c3e..2e4724bc4c 100644 --- a/redis.go +++ b/redis.go @@ -223,13 +223,6 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { username, password = c.opt.CredentialsProvider() } - if password == "" && - c.opt.DB == 0 && - !c.opt.readOnly && - c.opt.OnConnect == nil { - return nil - } - connPool := pool.NewSingleConnPool(c.connPool, cn) conn := newConn(ctx, c.opt, connPool) @@ -238,7 +231,7 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { // The low version of redis-server does not support the hello command. // For redis-server (<6.0) that does not support the Hello command, // we continue to provide services with RESP2. - if err := conn.Hello(ctx, 3, c.opt.Username, c.opt.Password, "").Err(); err == nil { + if err := conn.Hello(ctx, 3, username, password, "").Err(); err == nil { auth = true } else if err.Error() != "ERR unknown command 'hello'" { return err @@ -514,11 +507,12 @@ func wrapMultiExec(ctx context.Context, cmds []Cmder) []Cmder { } func txPipelineReadQueued(rd *proto.Reader, statusCmd *StatusCmd, cmds []Cmder) error { - // Parse queued replies. + // Parse +OK. if err := statusCmd.readReply(rd); err != nil { return err } + // Parse +QUEUED. for range cmds { if err := statusCmd.readReply(rd); err != nil && !isRedisError(err) { return err From c98c5f0eebf8d254307183c2ce702a48256b718d Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 16:20:10 +0300 Subject: [PATCH 038/621] fix: update ChannelWithSubscriptions to accept options --- go.mod | 1 - go.sum | 1 - pubsub.go | 4 ++-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index fdf1076b02..36eb801071 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.17 require ( github.com/cespare/xxhash/v2 v2.1.2 - github.com/davecgh/go-spew v1.1.1 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.19.0 diff --git a/go.sum b/go.sum index 53adb1790f..dfa31aac45 100644 --- a/go.sum +++ b/go.sum @@ -4,7 +4,6 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= diff --git a/pubsub.go b/pubsub.go index efc2354af0..3df2d65df9 100644 --- a/pubsub.go +++ b/pubsub.go @@ -456,9 +456,9 @@ func (c *PubSub) ChannelSize(size int) <-chan *Message { // reconnections. // // ChannelWithSubscriptions can not be used together with Channel or ChannelSize. -func (c *PubSub) ChannelWithSubscriptions(_ context.Context, size int) <-chan interface{} { +func (c *PubSub) ChannelWithSubscriptions(opts ...ChannelOption) <-chan interface{} { c.chOnce.Do(func() { - c.allCh = newChannel(c, WithChannelSize(size)) + c.allCh = newChannel(c, opts...) c.allCh.initAllChan() }) if c.allCh == nil { From d09c27e6046129fd27b1d275e5a13a477bd7f778 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 17:25:12 +0300 Subject: [PATCH 039/621] feat: upgrade to Redis 7 --- Makefile | 2 +- README.md | 6 + command.go | 256 ++++++++++++++++++++++++++++++--------- commands_test.go | 154 +++++------------------ export_test.go | 6 +- internal/proto/reader.go | 8 +- main_test.go | 17 ++- redis.go | 3 +- sentinel.go | 70 +++++------ 9 files changed, 293 insertions(+), 229 deletions(-) diff --git a/Makefile b/Makefile index 8dcddb24df..5dbd7ae837 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ bench: testdeps testdata/redis: mkdir -p $@ - wget -qO- https://download.redis.io/releases/redis-6.2.5.tar.gz | tar xvz --strip-components=1 -C $@ + wget -qO- https://download.redis.io/releases/redis-7.0.0.tar.gz | tar xvz --strip-components=1 -C $@ testdata/redis/src/redis-server: testdata/redis cd $< && make all diff --git a/README.md b/README.md index d218a52ba3..1b1543b1e3 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,12 @@ And then install go-redis/v8 (note _v8_ in the import; omitting it is a popular go get github.com/go-redis/redis/v8 ``` +If you need **Redis 7** support, install go-redis/v9: + +```shell +go get github.com/go-redis/redis/v9 +``` + ## Quickstart ```go diff --git a/command.go b/command.go index 1f4d646fac..51e7038889 100644 --- a/command.go +++ b/command.go @@ -1769,19 +1769,35 @@ func (cmd *XAutoClaimCmd) String() string { } func (cmd *XAutoClaimCmd) readReply(rd *proto.Reader) error { - var err error - if err = rd.ReadFixedArrayLen(2); err != nil { + n, err := rd.ReadArrayLen() + if err != nil { return err } + switch n { + case 2, // Redis 6 + 3: // Redis 7: + // ok + default: + return fmt.Errorf("redis: got %d elements in XAutoClaim reply, wanted 2/3", n) + } + cmd.start, err = rd.ReadString() if err != nil { return err } + cmd.val, err = readXMessageSlice(rd) if err != nil { return err } + + if n >= 3 { + if err := rd.DiscardNext(); err != nil { + return err + } + } + return nil } @@ -1823,27 +1839,43 @@ func (cmd *XAutoClaimJustIDCmd) String() string { } func (cmd *XAutoClaimJustIDCmd) readReply(rd *proto.Reader) error { - var err error - if err = rd.ReadFixedArrayLen(2); err != nil { + n, err := rd.ReadArrayLen() + if err != nil { return err } + switch n { + case 2, // Redis 6 + 3: // Redis 7: + // ok + default: + return fmt.Errorf("redis: got %d elements in XAutoClaimJustID reply, wanted 2/3", n) + } + cmd.start, err = rd.ReadString() if err != nil { return err } - n, err := rd.ReadArrayLen() + + nn, err := rd.ReadArrayLen() if err != nil { return err } - cmd.val = make([]string, n) - for i := 0; i < n; i++ { + cmd.val = make([]string, nn) + for i := 0; i < nn; i++ { cmd.val[i], err = rd.ReadString() if err != nil { return err } } + + if n >= 3 { + if err := rd.DiscardNext(); err != nil { + return err + } + } + return nil } @@ -1939,6 +1971,8 @@ type XInfoGroup struct { Consumers int64 Pending int64 LastDeliveredID string + EntriesRead int64 + Lag int64 } var _ Cmder = (*XInfoGroupsCmd)(nil) @@ -1976,12 +2010,15 @@ func (cmd *XInfoGroupsCmd) readReply(rd *proto.Reader) error { cmd.val = make([]XInfoGroup, n) for i := 0; i < len(cmd.val); i++ { - if err = rd.ReadFixedMapLen(4); err != nil { + group := &cmd.val[i] + + nn, err := rd.ReadMapLen() + if err != nil { return err } var key string - for f := 0; f < 4; f++ { + for j := 0; j < nn; j++ { key, err = rd.ReadString() if err != nil { return err @@ -1989,18 +2026,37 @@ func (cmd *XInfoGroupsCmd) readReply(rd *proto.Reader) error { switch key { case "name": - cmd.val[i].Name, err = rd.ReadString() + group.Name, err = rd.ReadString() + if err != nil { + return err + } case "consumers": - cmd.val[i].Consumers, err = rd.ReadInt() + group.Consumers, err = rd.ReadInt() + if err != nil { + return err + } case "pending": - cmd.val[i].Pending, err = rd.ReadInt() + group.Pending, err = rd.ReadInt() + if err != nil { + return err + } case "last-delivered-id": - cmd.val[i].LastDeliveredID, err = rd.ReadString() + group.LastDeliveredID, err = rd.ReadString() + if err != nil { + return err + } + case "entries-read": + group.EntriesRead, err = rd.ReadInt() + if err != nil { + return err + } + case "lag": + group.Lag, err = rd.ReadInt() + if err != nil { + return err + } default: - return fmt.Errorf("redis: unexpected content %s in XINFO GROUPS reply", key) - } - if err != nil { - return err + return fmt.Errorf("redis: unexpected key %q in XINFO GROUPS reply", key) } } } @@ -2016,13 +2072,16 @@ type XInfoStreamCmd struct { } type XInfoStream struct { - Length int64 - RadixTreeKeys int64 - RadixTreeNodes int64 - Groups int64 - LastGeneratedID string - FirstEntry XMessage - LastEntry XMessage + Length int64 + RadixTreeKeys int64 + RadixTreeNodes int64 + Groups int64 + LastGeneratedID string + MaxDeletedEntryID string + EntriesAdded int64 + FirstEntry XMessage + LastEntry XMessage + RecordedFirstEntryID string } var _ Cmder = (*XInfoStreamCmd)(nil) @@ -2053,12 +2112,13 @@ func (cmd *XInfoStreamCmd) String() string { } func (cmd *XInfoStreamCmd) readReply(rd *proto.Reader) error { - if err := rd.ReadFixedMapLen(7); err != nil { + n, err := rd.ReadMapLen() + if err != nil { return err } cmd.val = &XInfoStream{} - for i := 0; i < 7; i++ { + for i := 0; i < n; i++ { key, err := rd.ReadString() if err != nil { return err @@ -2066,30 +2126,56 @@ func (cmd *XInfoStreamCmd) readReply(rd *proto.Reader) error { switch key { case "length": cmd.val.Length, err = rd.ReadInt() + if err != nil { + return err + } case "radix-tree-keys": cmd.val.RadixTreeKeys, err = rd.ReadInt() + if err != nil { + return err + } case "radix-tree-nodes": cmd.val.RadixTreeNodes, err = rd.ReadInt() + if err != nil { + return err + } case "groups": cmd.val.Groups, err = rd.ReadInt() + if err != nil { + return err + } case "last-generated-id": cmd.val.LastGeneratedID, err = rd.ReadString() + if err != nil { + return err + } + case "max-deleted-entry-id": + cmd.val.MaxDeletedEntryID, err = rd.ReadString() + if err != nil { + return err + } + case "entries-added": + cmd.val.EntriesAdded, err = rd.ReadInt() + if err != nil { + return err + } case "first-entry": cmd.val.FirstEntry, err = readXMessage(rd) - if err == Nil { - err = nil + if err != nil && err != Nil { + return err } case "last-entry": cmd.val.LastEntry, err = readXMessage(rd) - if err == Nil { - err = nil + if err != nil && err != Nil { + return err + } + case "recorded-first-entry-id": + cmd.val.RecordedFirstEntryID, err = rd.ReadString() + if err != nil { + return err } default: - return fmt.Errorf("redis: unexpected content %s "+ - "in XINFO STREAM reply", key) - } - if err != nil { - return err + return fmt.Errorf("redis: unexpected key %q in XINFO STREAM reply", key) } } return nil @@ -2103,17 +2189,22 @@ type XInfoStreamFullCmd struct { } type XInfoStreamFull struct { - Length int64 - RadixTreeKeys int64 - RadixTreeNodes int64 - LastGeneratedID string - Entries []XMessage - Groups []XInfoStreamGroup + Length int64 + RadixTreeKeys int64 + RadixTreeNodes int64 + LastGeneratedID string + MaxDeletedEntryID string + EntriesAdded int64 + Entries []XMessage + Groups []XInfoStreamGroup + RecordedFirstEntryID string } type XInfoStreamGroup struct { Name string LastDeliveredID string + EntriesRead int64 + Lag int64 PelCount int64 Pending []XInfoStreamGroupPending Consumers []XInfoStreamConsumer @@ -2167,13 +2258,14 @@ func (cmd *XInfoStreamFullCmd) String() string { } func (cmd *XInfoStreamFullCmd) readReply(rd *proto.Reader) error { - if err := rd.ReadFixedMapLen(6); err != nil { + n, err := rd.ReadMapLen() + if err != nil { return err } cmd.val = &XInfoStreamFull{} - for i := 0; i < 6; i++ { + for i := 0; i < n; i++ { key, err := rd.ReadString() if err != nil { return err @@ -2182,22 +2274,51 @@ func (cmd *XInfoStreamFullCmd) readReply(rd *proto.Reader) error { switch key { case "length": cmd.val.Length, err = rd.ReadInt() + if err != nil { + return err + } case "radix-tree-keys": cmd.val.RadixTreeKeys, err = rd.ReadInt() + if err != nil { + return err + } case "radix-tree-nodes": cmd.val.RadixTreeNodes, err = rd.ReadInt() + if err != nil { + return err + } case "last-generated-id": cmd.val.LastGeneratedID, err = rd.ReadString() + if err != nil { + return err + } + case "entries-added": + cmd.val.EntriesAdded, err = rd.ReadInt() + if err != nil { + return err + } case "entries": cmd.val.Entries, err = readXMessageSlice(rd) + if err != nil { + return err + } case "groups": cmd.val.Groups, err = readStreamGroups(rd) + if err != nil { + return err + } + case "max-deleted-entry-id": + cmd.val.MaxDeletedEntryID, err = rd.ReadString() + if err != nil { + return err + } + case "recorded-first-entry-id": + cmd.val.RecordedFirstEntryID, err = rd.ReadString() + if err != nil { + return err + } default: - return fmt.Errorf("redis: unexpected content %s "+ - "in XINFO STREAM FULL reply", key) - } - if err != nil { - return err + return fmt.Errorf("redis: unexpected key %q in XINFO STREAM FULL reply", key) } } return nil @@ -2210,13 +2331,14 @@ func readStreamGroups(rd *proto.Reader) ([]XInfoStreamGroup, error) { } groups := make([]XInfoStreamGroup, 0, n) for i := 0; i < n; i++ { - if err = rd.ReadFixedMapLen(5); err != nil { + nn, err := rd.ReadMapLen() + if err != nil { return nil, err } group := XInfoStreamGroup{} - for f := 0; f < 5; f++ { + for j := 0; j < nn; j++ { key, err := rd.ReadString() if err != nil { return nil, err @@ -2225,21 +2347,41 @@ func readStreamGroups(rd *proto.Reader) ([]XInfoStreamGroup, error) { switch key { case "name": group.Name, err = rd.ReadString() + if err != nil { + return nil, err + } case "last-delivered-id": group.LastDeliveredID, err = rd.ReadString() + if err != nil { + return nil, err + } + case "entries-read": + group.EntriesRead, err = rd.ReadInt() + if err != nil { + return nil, err + } + case "lag": + group.Lag, err = rd.ReadInt() + if err != nil { + return nil, err + } case "pel-count": group.PelCount, err = rd.ReadInt() + if err != nil { + return nil, err + } case "pending": group.Pending, err = readXInfoStreamGroupPending(rd) + if err != nil { + return nil, err + } case "consumers": group.Consumers, err = readXInfoStreamConsumers(rd) + if err != nil { + return nil, err + } default: - return nil, fmt.Errorf("redis: unexpected content %s "+ - "in XINFO STREAM FULL reply", key) - } - - if err != nil { - return nil, err + return nil, fmt.Errorf("redis: unexpected key %q in XINFO STREAM FULL reply", key) } } @@ -2682,7 +2824,7 @@ func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error { if nn >= 4 { networkingMetadata := make(map[string]string) - metadataLength, err := rd.ReadArrayLen() + metadataLength, err := rd.ReadMapLen() if err != nil { return err } diff --git a/commands_test.go b/commands_test.go index 81c1bdb878..a7347e6751 100644 --- a/commands_test.go +++ b/commands_test.go @@ -259,7 +259,7 @@ var _ = Describe("Commands", func() { It("should Command", func() { cmds, err := client.Command(ctx).Result() Expect(err).NotTo(HaveOccurred()) - Expect(len(cmds)).To(BeNumerically("~", 200, 25)) + Expect(len(cmds)).To(BeNumerically("~", 240, 25)) cmd := cmds["mget"] Expect(cmd.Name).To(Equal("mget")) @@ -272,7 +272,6 @@ var _ = Describe("Commands", func() { cmd = cmds["ping"] Expect(cmd.Name).To(Equal("ping")) Expect(cmd.Arity).To(Equal(int8(-1))) - Expect(cmd.Flags).To(ContainElement("stale")) Expect(cmd.Flags).To(ContainElement("fast")) Expect(cmd.FirstKeyPos).To(Equal(int8(0))) Expect(cmd.LastKeyPos).To(Equal(int8(0))) @@ -281,7 +280,7 @@ var _ = Describe("Commands", func() { }) Describe("debugging", func() { - It("should DebugObject", func() { + PIt("should DebugObject", func() { err := client.DebugObject(ctx, "foo").Err() Expect(err).To(MatchError("ERR no such key")) @@ -1309,7 +1308,7 @@ var _ = Describe("Commands", func() { Get: true, } val, err := client.SetArgs(ctx, "key", "hello", args).Result() - Expect(err).To(Equal(proto.RedisError("ERR syntax error"))) + Expect(err).To(Equal(redis.Nil)) Expect(val).To(Equal("")) }) @@ -1347,7 +1346,7 @@ var _ = Describe("Commands", func() { Get: true, } val, err := client.SetArgs(ctx, "key", "hello", args).Result() - Expect(err).To(Equal(proto.RedisError("ERR syntax error"))) + Expect(err).To(Equal(redis.Nil)) Expect(val).To(Equal("")) }) @@ -4838,13 +4837,22 @@ var _ = Describe("Commands", func() { res.RadixTreeNodes = 0 Expect(res).To(Equal(&redis.XInfoStream{ - Length: 3, - RadixTreeKeys: 0, - RadixTreeNodes: 0, - Groups: 2, - LastGeneratedID: "3-0", - FirstEntry: redis.XMessage{ID: "1-0", Values: map[string]interface{}{"uno": "un"}}, - LastEntry: redis.XMessage{ID: "3-0", Values: map[string]interface{}{"tres": "troix"}}, + Length: 3, + RadixTreeKeys: 0, + RadixTreeNodes: 0, + Groups: 2, + LastGeneratedID: "3-0", + MaxDeletedEntryID: "0-0", + EntriesAdded: 3, + FirstEntry: redis.XMessage{ + ID: "1-0", + Values: map[string]interface{}{"uno": "un"}, + }, + LastEntry: redis.XMessage{ + ID: "3-0", + Values: map[string]interface{}{"tres": "troix"}, + }, + RecordedFirstEntryID: "1-0", })) // stream is empty @@ -4858,13 +4866,16 @@ var _ = Describe("Commands", func() { res.RadixTreeNodes = 0 Expect(res).To(Equal(&redis.XInfoStream{ - Length: 0, - RadixTreeKeys: 0, - RadixTreeNodes: 0, - Groups: 2, - LastGeneratedID: "3-0", - FirstEntry: redis.XMessage{}, - LastEntry: redis.XMessage{}, + Length: 0, + RadixTreeKeys: 0, + RadixTreeNodes: 0, + Groups: 2, + LastGeneratedID: "3-0", + MaxDeletedEntryID: "3-0", + EntriesAdded: 3, + FirstEntry: redis.XMessage{}, + LastEntry: redis.XMessage{}, + RecordedFirstEntryID: "0-0", })) }) @@ -4892,115 +4903,14 @@ var _ = Describe("Commands", func() { } } } - - Expect(res).To(Equal(&redis.XInfoStreamFull{ - Length: 3, - RadixTreeKeys: 0, - RadixTreeNodes: 0, - LastGeneratedID: "3-0", - Entries: []redis.XMessage{ - {ID: "1-0", Values: map[string]interface{}{"uno": "un"}}, - {ID: "2-0", Values: map[string]interface{}{"dos": "deux"}}, - }, - Groups: []redis.XInfoStreamGroup{ - { - Name: "group1", - LastDeliveredID: "3-0", - PelCount: 3, - Pending: []redis.XInfoStreamGroupPending{ - { - ID: "1-0", - Consumer: "consumer1", - DeliveryTime: time.Time{}, - DeliveryCount: 1, - }, - { - ID: "2-0", - Consumer: "consumer1", - DeliveryTime: time.Time{}, - DeliveryCount: 1, - }, - }, - Consumers: []redis.XInfoStreamConsumer{ - { - Name: "consumer1", - SeenTime: time.Time{}, - PelCount: 2, - Pending: []redis.XInfoStreamConsumerPending{ - { - ID: "1-0", - DeliveryTime: time.Time{}, - DeliveryCount: 1, - }, - { - ID: "2-0", - DeliveryTime: time.Time{}, - DeliveryCount: 1, - }, - }, - }, - { - Name: "consumer2", - SeenTime: time.Time{}, - PelCount: 1, - Pending: []redis.XInfoStreamConsumerPending{ - { - ID: "3-0", - DeliveryTime: time.Time{}, - DeliveryCount: 1, - }, - }, - }, - }, - }, - { - Name: "group2", - LastDeliveredID: "3-0", - PelCount: 2, - Pending: []redis.XInfoStreamGroupPending{ - { - ID: "2-0", - Consumer: "consumer1", - DeliveryTime: time.Time{}, - DeliveryCount: 1, - }, - { - ID: "3-0", - Consumer: "consumer1", - DeliveryTime: time.Time{}, - DeliveryCount: 1, - }, - }, - Consumers: []redis.XInfoStreamConsumer{ - { - Name: "consumer1", - SeenTime: time.Time{}, - PelCount: 2, - Pending: []redis.XInfoStreamConsumerPending{ - { - ID: "2-0", - DeliveryTime: time.Time{}, - DeliveryCount: 1, - }, - { - ID: "3-0", - DeliveryTime: time.Time{}, - DeliveryCount: 1, - }, - }, - }, - }, - }, - }, - })) }) It("should XINFO GROUPS", func() { res, err := client.XInfoGroups(ctx, "stream").Result() Expect(err).NotTo(HaveOccurred()) Expect(res).To(Equal([]redis.XInfoGroup{ - {Name: "group1", Consumers: 2, Pending: 3, LastDeliveredID: "3-0"}, - {Name: "group2", Consumers: 1, Pending: 2, LastDeliveredID: "3-0"}, + {Name: "group1", Consumers: 2, Pending: 3, LastDeliveredID: "3-0", EntriesRead: 3}, + {Name: "group2", Consumers: 1, Pending: 2, LastDeliveredID: "3-0", EntriesRead: 3}, })) }) diff --git a/export_test.go b/export_test.go index e243a19274..64ba35f505 100644 --- a/export_test.go +++ b/export_test.go @@ -85,11 +85,11 @@ func (c *clusterState) IsConsistent(ctx context.Context) bool { } func GetSlavesAddrByName(ctx context.Context, c *SentinelClient, name string) []string { - addrs, err := c.Slaves(ctx, name).Result() + addrs, err := c.Replicas(ctx, name).Result() if err != nil { - internal.Logger.Printf(ctx, "sentinel: Slaves name=%q failed: %s", + internal.Logger.Printf(ctx, "sentinel: Replicas name=%q failed: %s", name, err) return []string{} } - return parseSlaveAddrs(addrs, false) + return parseReplicaAddrs(addrs, false) } diff --git a/internal/proto/reader.go b/internal/proto/reader.go index b330f5944b..ac24f28a2e 100644 --- a/internal/proto/reader.go +++ b/internal/proto/reader.go @@ -388,7 +388,7 @@ func (r *Reader) ReadFixedArrayLen(fixedLen int) error { return err } if n != fixedLen { - return fmt.Errorf("redis: got %d elements of array length, wanted %d", n, fixedLen) + return fmt.Errorf("redis: got %d elements in the array, wanted %d", n, fixedLen) } return nil } @@ -407,19 +407,19 @@ func (r *Reader) ReadArrayLen() (int, error) { } } -// ReadFixedMapLen read fixed map length. +// ReadFixedMapLen reads fixed map length. func (r *Reader) ReadFixedMapLen(fixedLen int) error { n, err := r.ReadMapLen() if err != nil { return err } if n != fixedLen { - return fmt.Errorf("redis: got %d elements of map length, wanted %d", n, fixedLen) + return fmt.Errorf("redis: got %d elements in the map, wanted %d", n, fixedLen) } return nil } -// ReadMapLen read the length of the map type. +// ReadMapLen reads the length of the map type. // If responding to the array type (RespArray/RespSet/RespPush), // it must be a multiple of 2 and return n/2. // Other types will return an error. diff --git a/main_test.go b/main_test.go index 5529112e95..c52140dfc9 100644 --- a/main_test.go +++ b/main_test.go @@ -283,8 +283,9 @@ func (p *redisProcess) Close() error { } var ( - redisServerBin, _ = filepath.Abs(filepath.Join("testdata", "redis", "src", "redis-server")) - redisServerConf, _ = filepath.Abs(filepath.Join("testdata", "redis", "redis.conf")) + redisServerBin, _ = filepath.Abs(filepath.Join("testdata", "redis", "src", "redis-server")) + redisServerConf, _ = filepath.Abs(filepath.Join("testdata", "redis", "redis.conf")) + redisSentinelConf, _ = filepath.Abs(filepath.Join("testdata", "redis", "sentinel.conf")) ) func redisDir(port string) (string, error) { @@ -306,7 +307,8 @@ func startRedis(port string, args ...string) (*redisProcess, error) { if err != nil { return nil, err } - if err = exec.Command("cp", "-f", redisServerConf, dir).Run(); err != nil { + + if err := exec.Command("cp", "-f", redisServerConf, dir).Run(); err != nil { return nil, err } @@ -333,7 +335,12 @@ func startSentinel(port, masterName, masterPort string) (*redisProcess, error) { return nil, err } - process, err := execCmd(redisServerBin, os.DevNull, "--sentinel", "--port", port, "--dir", dir) + sentinelConf := filepath.Join(dir, "sentinel.conf") + if err := os.WriteFile(sentinelConf, nil, 0o644); err != nil { + return nil, err + } + + process, err := execCmd(redisServerBin, sentinelConf, "--sentinel", "--port", port, "--dir", dir) if err != nil { return nil, err } @@ -355,7 +362,7 @@ func startSentinel(port, masterName, masterPort string) (*redisProcess, error) { client.Process(ctx, cmd) if err := cmd.Err(); err != nil { process.Kill() - return nil, err + return nil, fmt.Errorf("%s failed: %w", cmd, err) } } diff --git a/redis.go b/redis.go index 2e4724bc4c..8320669edf 100644 --- a/redis.go +++ b/redis.go @@ -228,8 +228,7 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { var auth bool - // The low version of redis-server does not support the hello command. - // For redis-server (<6.0) that does not support the Hello command, + // For redis-server <6.0 that does not support the Hello command, // we continue to provide services with RESP2. if err := conn.Hello(ctx, 3, username, password, "").Err(); err == nil { auth = true diff --git a/sentinel.go b/sentinel.go index 205f8a123b..e133d7a069 100644 --- a/sentinel.go +++ b/sentinel.go @@ -32,19 +32,19 @@ type FailoverOptions struct { // authentication. SentinelPassword string - // Allows routing read-only commands to the closest master or slave node. + // Allows routing read-only commands to the closest master or replica node. // This option only works with NewFailoverClusterClient. RouteByLatency bool - // Allows routing read-only commands to the random master or slave node. + // Allows routing read-only commands to the random master or replica node. // This option only works with NewFailoverClusterClient. RouteRandomly bool - // Route all commands to slave read-only nodes. - SlaveOnly bool + // Route all commands to replica read-only nodes. + ReplicaOnly bool - // Use slaves disconnected with master when cannot get connected slaves - // Now, this option only works in RandomSlaveAddr function. - UseDisconnectedSlaves bool + // Use replicas disconnected with master when cannot get connected replicas + // Now, this option only works in RandomReplicaAddr function. + UseDisconnectedReplicas bool // Following options are copied from Options struct. @@ -194,7 +194,7 @@ func NewFailoverClient(failoverOpt *FailoverOptions) *Client { } opt := failoverOpt.clientOptions() - opt.Dialer = masterSlaveDialer(failover) + opt.Dialer = masterReplicaDialer(failover) opt.init() connPool := newConnPool(opt) @@ -217,15 +217,15 @@ func NewFailoverClient(failoverOpt *FailoverOptions) *Client { return &c } -func masterSlaveDialer( +func masterReplicaDialer( failover *sentinelFailover, ) func(ctx context.Context, network, addr string) (net.Conn, error) { return func(ctx context.Context, network, _ string) (net.Conn, error) { var addr string var err error - if failover.opt.SlaveOnly { - addr, err = failover.RandomSlaveAddr(ctx) + if failover.opt.ReplicaOnly { + addr, err = failover.RandomReplicaAddr(ctx) } else { addr, err = failover.MasterAddr(ctx) if err == nil { @@ -351,7 +351,7 @@ func (c *SentinelClient) Failover(ctx context.Context, name string) *StatusCmd { // Reset resets all the masters with matching name. The pattern argument is a // glob-style pattern. The reset process clears any previous state in a master -// (including a failover in progress), and removes every slave and sentinel +// (including a failover in progress), and removes every replica and sentinel // already discovered and associated with the master. func (c *SentinelClient) Reset(ctx context.Context, pattern string) *IntCmd { cmd := NewIntCmd(ctx, "sentinel", "reset", pattern) @@ -381,9 +381,9 @@ func (c *SentinelClient) Masters(ctx context.Context) *SliceCmd { return cmd } -// Slaves shows a list of slaves for the specified master and their state. -func (c *SentinelClient) Slaves(ctx context.Context, name string) *MapStringStringSliceCmd { - cmd := NewMapStringStringSliceCmd(ctx, "sentinel", "slaves", name) +// Replicas shows a list of replicas for the specified master and their state. +func (c *SentinelClient) Replicas(ctx context.Context, name string) *MapStringStringSliceCmd { + cmd := NewMapStringStringSliceCmd(ctx, "sentinel", "replicas", name) _ = c.Process(ctx, cmd) return cmd } @@ -460,18 +460,18 @@ func (c *sentinelFailover) closeSentinel() error { return firstErr } -func (c *sentinelFailover) RandomSlaveAddr(ctx context.Context) (string, error) { +func (c *sentinelFailover) RandomReplicaAddr(ctx context.Context) (string, error) { if c.opt == nil { return "", errors.New("opt is nil") } - addresses, err := c.slaveAddrs(ctx, false) + addresses, err := c.replicaAddrs(ctx, false) if err != nil { return "", err } - if len(addresses) == 0 && c.opt.UseDisconnectedSlaves { - addresses, err = c.slaveAddrs(ctx, true) + if len(addresses) == 0 && c.opt.UseDisconnectedReplicas { + addresses, err = c.replicaAddrs(ctx, true) if err != nil { return "", err } @@ -528,13 +528,13 @@ func (c *sentinelFailover) MasterAddr(ctx context.Context) (string, error) { return "", errors.New("redis: all sentinels specified in configuration are unreachable") } -func (c *sentinelFailover) slaveAddrs(ctx context.Context, useDisconnected bool) ([]string, error) { +func (c *sentinelFailover) replicaAddrs(ctx context.Context, useDisconnected bool) ([]string, error) { c.mu.RLock() sentinel := c.sentinel c.mu.RUnlock() if sentinel != nil { - addrs := c.getSlaveAddrs(ctx, sentinel) + addrs := c.getReplicaAddrs(ctx, sentinel) if len(addrs) > 0 { return addrs, nil } @@ -544,7 +544,7 @@ func (c *sentinelFailover) slaveAddrs(ctx context.Context, useDisconnected bool) defer c.mu.Unlock() if c.sentinel != nil { - addrs := c.getSlaveAddrs(ctx, c.sentinel) + addrs := c.getReplicaAddrs(ctx, c.sentinel) if len(addrs) > 0 { return addrs, nil } @@ -556,15 +556,15 @@ func (c *sentinelFailover) slaveAddrs(ctx context.Context, useDisconnected bool) for i, sentinelAddr := range c.sentinelAddrs { sentinel := NewSentinelClient(c.opt.sentinelOptions(sentinelAddr)) - slaves, err := sentinel.Slaves(ctx, c.opt.MasterName).Result() + replicas, err := sentinel.Replicas(ctx, c.opt.MasterName).Result() if err != nil { - internal.Logger.Printf(ctx, "sentinel: Slaves master=%q failed: %s", + internal.Logger.Printf(ctx, "sentinel: Replicas master=%q failed: %s", c.opt.MasterName, err) _ = sentinel.Close() continue } sentinelReachable = true - addrs := parseSlaveAddrs(slaves, useDisconnected) + addrs := parseReplicaAddrs(replicas, useDisconnected) if len(addrs) == 0 { continue } @@ -591,17 +591,17 @@ func (c *sentinelFailover) getMasterAddr(ctx context.Context, sentinel *Sentinel return net.JoinHostPort(addr[0], addr[1]) } -func (c *sentinelFailover) getSlaveAddrs(ctx context.Context, sentinel *SentinelClient) []string { - addrs, err := sentinel.Slaves(ctx, c.opt.MasterName).Result() +func (c *sentinelFailover) getReplicaAddrs(ctx context.Context, sentinel *SentinelClient) []string { + addrs, err := sentinel.Replicas(ctx, c.opt.MasterName).Result() if err != nil { - internal.Logger.Printf(ctx, "sentinel: Slaves name=%q failed: %s", + internal.Logger.Printf(ctx, "sentinel: Replicas name=%q failed: %s", c.opt.MasterName, err) return []string{} } - return parseSlaveAddrs(addrs, false) + return parseReplicaAddrs(addrs, false) } -func parseSlaveAddrs(addrs []map[string]string, keepDisconnected bool) []string { +func parseReplicaAddrs(addrs []map[string]string, keepDisconnected bool) []string { nodes := make([]string, 0, len(addrs)) for _, node := range addrs { isDown := false @@ -656,7 +656,7 @@ func (c *sentinelFailover) setSentinel(ctx context.Context, sentinel *SentinelCl c.sentinel = sentinel c.discoverSentinels(ctx) - c.pubsub = sentinel.Subscribe(ctx, "+switch-master", "+slave-reconf-done") + c.pubsub = sentinel.Subscribe(ctx, "+switch-master", "+replica-reconf-done") go c.listen(c.pubsub) } @@ -723,7 +723,7 @@ func contains(slice []string, str string) bool { //------------------------------------------------------------------------------ // NewFailoverClusterClient returns a client that supports routing read-only commands -// to a slave node. +// to a replica node. func NewFailoverClusterClient(failoverOpt *FailoverOptions) *ClusterClient { sentinelAddrs := make([]string, len(failoverOpt.SentinelAddrs)) copy(sentinelAddrs, failoverOpt.SentinelAddrs) @@ -744,14 +744,14 @@ func NewFailoverClusterClient(failoverOpt *FailoverOptions) *ClusterClient { Addr: masterAddr, }} - slaveAddrs, err := failover.slaveAddrs(ctx, false) + replicaAddrs, err := failover.replicaAddrs(ctx, false) if err != nil { return nil, err } - for _, slaveAddr := range slaveAddrs { + for _, replicaAddr := range replicaAddrs { nodes = append(nodes, ClusterNode{ - Addr: slaveAddr, + Addr: replicaAddr, }) } From a18fad5bd311a93a5348ed11ff5d028b82df039a Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 17:39:21 +0300 Subject: [PATCH 040/621] chore: v9 --- README.md | 4 ++-- bench_decode_test.go | 2 +- bench_test.go | 2 +- cluster.go | 10 +++++----- cluster_test.go | 4 ++-- command.go | 8 ++++---- command_test.go | 2 +- commands.go | 2 +- commands_test.go | 4 ++-- error.go | 4 ++-- example/del-keys-without-ttl/go.mod | 4 ++-- example/del-keys-without-ttl/main.go | 2 +- example/hll/go.mod | 4 ++-- example/hll/main.go | 2 +- example/lua-scripting/go.mod | 4 ++-- example/lua-scripting/main.go | 2 +- example/otel/go.mod | 8 +++----- example/otel/main.go | 4 ++-- example/redis-bloom/go.mod | 4 ++-- example/redis-bloom/main.go | 2 +- example/scan-struct/go.mod | 4 ++-- example/scan-struct/main.go | 2 +- example_instrumentation_test.go | 2 +- example_test.go | 2 +- export_test.go | 6 +++--- extra/rediscensus/go.mod | 8 +++----- extra/rediscensus/rediscensus.go | 4 ++-- extra/rediscmd/go.mod | 5 ++--- extra/rediscmd/rediscmd.go | 2 +- extra/redisotel/README.md | 6 +++--- extra/redisotel/go.mod | 8 +++----- extra/redisotel/redisotel.go | 4 ++-- extra/redisotel/redisotel_test.go | 4 ++-- fuzz/fuzz.go | 2 +- go.mod | 2 +- internal/hashtag/hashtag.go | 2 +- internal/hashtag/hashtag_test.go | 2 +- internal/internal.go | 2 +- internal/pool/bench_test.go | 2 +- internal/pool/conn.go | 2 +- internal/pool/pool.go | 2 +- internal/pool/pool_test.go | 2 +- internal/proto/reader.go | 2 +- internal/proto/reader_test.go | 2 +- internal/proto/scan.go | 2 +- internal/proto/scan_test.go | 2 +- internal/proto/writer.go | 2 +- internal/proto/writer_test.go | 2 +- internal/util.go | 2 +- iterator_test.go | 2 +- main_test.go | 2 +- options.go | 2 +- pipeline_test.go | 2 +- pool_test.go | 2 +- pubsub.go | 6 +++--- pubsub_test.go | 2 +- race_test.go | 2 +- redis.go | 6 +++--- redis_test.go | 2 +- ring.go | 8 ++++---- ring_test.go | 2 +- sentinel.go | 6 +++--- sentinel_test.go | 2 +- tx.go | 4 ++-- tx_test.go | 2 +- universal_test.go | 2 +- 66 files changed, 107 insertions(+), 114 deletions(-) diff --git a/README.md b/README.md index 1b1543b1e3..bb2ebcca67 100644 --- a/README.md +++ b/README.md @@ -63,13 +63,13 @@ module: go mod init github.com/my/repo ``` -And then install go-redis/v8 (note _v8_ in the import; omitting it is a popular mistake): +If you are using **Redis 6**, install go-redis/**v8**: ```shell go get github.com/go-redis/redis/v8 ``` -If you need **Redis 7** support, install go-redis/v9: +If you are using **Redis 7**, install **go-redis/v9**: ```shell go get github.com/go-redis/redis/v9 diff --git a/bench_decode_test.go b/bench_decode_test.go index 753130e28f..fc929e52cd 100644 --- a/bench_decode_test.go +++ b/bench_decode_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v9/internal/proto" ) var ctx = context.TODO() diff --git a/bench_test.go b/bench_test.go index df43d89010..4af5184253 100644 --- a/bench_test.go +++ b/bench_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) func benchmarkRedisClient(ctx context.Context, poolSize int) *redis.Client { diff --git a/cluster.go b/cluster.go index 27dd31b38f..b3e7a8cd35 100644 --- a/cluster.go +++ b/cluster.go @@ -12,11 +12,11 @@ import ( "sync/atomic" "time" - "github.com/go-redis/redis/v8/internal" - "github.com/go-redis/redis/v8/internal/hashtag" - "github.com/go-redis/redis/v8/internal/pool" - "github.com/go-redis/redis/v8/internal/proto" - "github.com/go-redis/redis/v8/internal/rand" + "github.com/go-redis/redis/v9/internal" + "github.com/go-redis/redis/v9/internal/hashtag" + "github.com/go-redis/redis/v9/internal/pool" + "github.com/go-redis/redis/v9/internal/proto" + "github.com/go-redis/redis/v9/internal/rand" ) var errClusterNoNodes = fmt.Errorf("redis: cluster has no nodes") diff --git a/cluster_test.go b/cluster_test.go index 2d2021cf53..59fcef2f30 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -12,8 +12,8 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" - "github.com/go-redis/redis/v8/internal/hashtag" + "github.com/go-redis/redis/v9" + "github.com/go-redis/redis/v9/internal/hashtag" ) type clusterScenario struct { diff --git a/command.go b/command.go index 51e7038889..ee1e8d17a9 100644 --- a/command.go +++ b/command.go @@ -7,10 +7,10 @@ import ( "strconv" "time" - "github.com/go-redis/redis/v8/internal" - "github.com/go-redis/redis/v8/internal/hscan" - "github.com/go-redis/redis/v8/internal/proto" - "github.com/go-redis/redis/v8/internal/util" + "github.com/go-redis/redis/v9/internal" + "github.com/go-redis/redis/v9/internal/hscan" + "github.com/go-redis/redis/v9/internal/proto" + "github.com/go-redis/redis/v9/internal/util" ) type Cmder interface { diff --git a/command_test.go b/command_test.go index 775987fc1a..9af156c88d 100644 --- a/command_test.go +++ b/command_test.go @@ -4,7 +4,7 @@ import ( "errors" "time" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" diff --git a/commands.go b/commands.go index 60997a8f64..beb3af2d16 100644 --- a/commands.go +++ b/commands.go @@ -6,7 +6,7 @@ import ( "io" "time" - "github.com/go-redis/redis/v8/internal" + "github.com/go-redis/redis/v9/internal" ) // KeepTTL is a Redis KEEPTTL option to keep existing TTL, it requires your redis-server version >= 6.0, diff --git a/commands_test.go b/commands_test.go index a7347e6751..fd5f9c7595 100644 --- a/commands_test.go +++ b/commands_test.go @@ -10,8 +10,8 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" - "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v9" + "github.com/go-redis/redis/v9/internal/proto" ) var _ = Describe("Commands", func() { diff --git a/error.go b/error.go index a6567eff12..32328511d0 100644 --- a/error.go +++ b/error.go @@ -6,8 +6,8 @@ import ( "net" "strings" - "github.com/go-redis/redis/v8/internal/pool" - "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v9/internal/pool" + "github.com/go-redis/redis/v9/internal/proto" ) // ErrClosed performs any operation on the closed client will return this error. diff --git a/example/del-keys-without-ttl/go.mod b/example/del-keys-without-ttl/go.mod index 4421e29f25..435f636e77 100644 --- a/example/del-keys-without-ttl/go.mod +++ b/example/del-keys-without-ttl/go.mod @@ -2,6 +2,6 @@ module github.com/go-redis/redis/example/del-keys-without-ttl go 1.14 -replace github.com/go-redis/redis/v8 => ../.. +replace github.com/go-redis/redis/v9 => ../.. -require github.com/go-redis/redis/v8 v8.11.5 +require github.com/go-redis/redis/v9 v8.11.5 diff --git a/example/del-keys-without-ttl/main.go b/example/del-keys-without-ttl/main.go index 2331ed1027..8ac2a07860 100644 --- a/example/del-keys-without-ttl/main.go +++ b/example/del-keys-without-ttl/main.go @@ -5,7 +5,7 @@ import ( "fmt" "sync" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) func main() { diff --git a/example/hll/go.mod b/example/hll/go.mod index 33d76306d5..42800bcd02 100644 --- a/example/hll/go.mod +++ b/example/hll/go.mod @@ -2,6 +2,6 @@ module github.com/go-redis/redis/example/hll go 1.14 -replace github.com/go-redis/redis/v8 => ../.. +replace github.com/go-redis/redis/v9 => ../.. -require github.com/go-redis/redis/v8 v8.11.5 +require github.com/go-redis/redis/v9 v8.11.5 diff --git a/example/hll/main.go b/example/hll/main.go index 60a957e9ca..db9d2673a1 100644 --- a/example/hll/main.go +++ b/example/hll/main.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) func main() { diff --git a/example/lua-scripting/go.mod b/example/lua-scripting/go.mod index be4ecab23e..d30d832872 100644 --- a/example/lua-scripting/go.mod +++ b/example/lua-scripting/go.mod @@ -2,6 +2,6 @@ module github.com/go-redis/redis/example/redis-bloom go 1.14 -replace github.com/go-redis/redis/v8 => ../.. +replace github.com/go-redis/redis/v9 => ../.. -require github.com/go-redis/redis/v8 v8.11.5 +require github.com/go-redis/redis/v9 v8.11.5 diff --git a/example/lua-scripting/main.go b/example/lua-scripting/main.go index 04cb44d939..e86fd83634 100644 --- a/example/lua-scripting/main.go +++ b/example/lua-scripting/main.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) func main() { diff --git a/example/otel/go.mod b/example/otel/go.mod index afe12ab8d4..1203d9e9ab 100644 --- a/example/otel/go.mod +++ b/example/otel/go.mod @@ -2,15 +2,13 @@ module github.com/go-redis/redis/example/otel go 1.14 -replace github.com/go-redis/redis/v8 => ../.. +replace github.com/go-redis/redis/v9 => ../.. -replace github.com/go-redis/redis/extra/redisotel/v8 => ../../extra/redisotel +replace github.com/go-redis/redis/extra/redisotel/v9 => ../../extra/redisotel -replace github.com/go-redis/redis/extra/rediscmd/v8 => ../../extra/rediscmd +replace github.com/go-redis/redis/extra/rediscmd/v9 => ../../extra/rediscmd require ( - github.com/go-redis/redis/extra/redisotel/v8 v8.11.5 - github.com/go-redis/redis/v8 v8.11.5 github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.10 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/exporters/jaeger v1.5.0 // indirect diff --git a/example/otel/main.go b/example/otel/main.go index 952b24b74f..75033ebfc3 100644 --- a/example/otel/main.go +++ b/example/otel/main.go @@ -10,8 +10,8 @@ import ( "go.opentelemetry.io/otel/codes" semconv "go.opentelemetry.io/otel/semconv/v1.7.0" - "github.com/go-redis/redis/extra/redisotel/v8" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/extra/redisotel/v9" + "github.com/go-redis/redis/v9" ) var tracer = otel.Tracer("redisexample") diff --git a/example/redis-bloom/go.mod b/example/redis-bloom/go.mod index be4ecab23e..d30d832872 100644 --- a/example/redis-bloom/go.mod +++ b/example/redis-bloom/go.mod @@ -2,6 +2,6 @@ module github.com/go-redis/redis/example/redis-bloom go 1.14 -replace github.com/go-redis/redis/v8 => ../.. +replace github.com/go-redis/redis/v9 => ../.. -require github.com/go-redis/redis/v8 v8.11.5 +require github.com/go-redis/redis/v9 v8.11.5 diff --git a/example/redis-bloom/main.go b/example/redis-bloom/main.go index c2ae7c08ad..452026eb76 100644 --- a/example/redis-bloom/main.go +++ b/example/redis-bloom/main.go @@ -5,7 +5,7 @@ import ( "fmt" "math/rand" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) func main() { diff --git a/example/scan-struct/go.mod b/example/scan-struct/go.mod index 8c42bef376..40a2930929 100644 --- a/example/scan-struct/go.mod +++ b/example/scan-struct/go.mod @@ -2,9 +2,9 @@ module github.com/go-redis/redis/example/scan-struct go 1.14 -replace github.com/go-redis/redis/v8 => ../.. +replace github.com/go-redis/redis/v9 => ../.. require ( github.com/davecgh/go-spew v1.1.1 - github.com/go-redis/redis/v8 v8.11.5 + github.com/go-redis/redis/v9 v8.11.5 ) diff --git a/example/scan-struct/main.go b/example/scan-struct/main.go index aee7ef715e..d53b654848 100644 --- a/example/scan-struct/main.go +++ b/example/scan-struct/main.go @@ -5,7 +5,7 @@ import ( "github.com/davecgh/go-spew/spew" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) type Model struct { diff --git a/example_instrumentation_test.go b/example_instrumentation_test.go index d66edce2d6..639f9f0e80 100644 --- a/example_instrumentation_test.go +++ b/example_instrumentation_test.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) type redisHook struct{} diff --git a/example_test.go b/example_test.go index 75b5cbbb3a..3e05f21b45 100644 --- a/example_test.go +++ b/example_test.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var ( diff --git a/export_test.go b/export_test.go index 64ba35f505..5e6d746681 100644 --- a/export_test.go +++ b/export_test.go @@ -6,9 +6,9 @@ import ( "net" "strings" - "github.com/go-redis/redis/v8/internal" - "github.com/go-redis/redis/v8/internal/hashtag" - "github.com/go-redis/redis/v8/internal/pool" + "github.com/go-redis/redis/v9/internal" + "github.com/go-redis/redis/v9/internal/hashtag" + "github.com/go-redis/redis/v9/internal/pool" ) func (c *baseClient) Pool() pool.Pooler { diff --git a/extra/rediscensus/go.mod b/extra/rediscensus/go.mod index 8f82a0c805..1a7f808029 100644 --- a/extra/rediscensus/go.mod +++ b/extra/rediscensus/go.mod @@ -1,14 +1,12 @@ -module github.com/go-redis/redis/extra/rediscensus/v8 +module github.com/go-redis/redis/extra/rediscensus/v9 go 1.15 -replace github.com/go-redis/redis/v8 => ../.. +replace github.com/go-redis/redis/v9 => ../.. -replace github.com/go-redis/redis/extra/rediscmd/v8 => ../rediscmd +replace github.com/go-redis/redis/extra/rediscmd/v9 => ../rediscmd require ( - github.com/go-redis/redis/extra/rediscmd/v8 v8.11.5 - github.com/go-redis/redis/v8 v8.11.5 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect go.opencensus.io v0.23.0 ) diff --git a/extra/rediscensus/rediscensus.go b/extra/rediscensus/rediscensus.go index 9af094e944..c92e41b1e5 100644 --- a/extra/rediscensus/rediscensus.go +++ b/extra/rediscensus/rediscensus.go @@ -5,8 +5,8 @@ import ( "go.opencensus.io/trace" - "github.com/go-redis/redis/extra/rediscmd/v8" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/extra/rediscmd/v9" + "github.com/go-redis/redis/v9" ) type TracingHook struct{} diff --git a/extra/rediscmd/go.mod b/extra/rediscmd/go.mod index 1bc5bef4bf..f600c19cb5 100644 --- a/extra/rediscmd/go.mod +++ b/extra/rediscmd/go.mod @@ -1,11 +1,10 @@ -module github.com/go-redis/redis/extra/rediscmd/v8 +module github.com/go-redis/redis/extra/rediscmd/v9 go 1.15 -replace github.com/go-redis/redis/v8 => ../.. +replace github.com/go-redis/redis/v9 => ../.. require ( - github.com/go-redis/redis/v8 v8.11.5 github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.18.1 ) diff --git a/extra/rediscmd/rediscmd.go b/extra/rediscmd/rediscmd.go index 12ea39fc1e..e47a158a4e 100644 --- a/extra/rediscmd/rediscmd.go +++ b/extra/rediscmd/rediscmd.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) func CmdString(cmd redis.Cmder) string { diff --git a/extra/redisotel/README.md b/extra/redisotel/README.md index fae4032f53..66c33c9c9b 100644 --- a/extra/redisotel/README.md +++ b/extra/redisotel/README.md @@ -3,7 +3,7 @@ ## Installation ```bash -go get github.com/go-redis/redis/extra/redisotel/v8 +go get github.com/go-redis/redis/extra/redisotel/v9 ``` ## Usage @@ -12,8 +12,8 @@ Tracing is enabled by adding a hook: ```go import ( - "github.com/go-redis/redis/v8" - "github.com/go-redis/redis/extra/redisotel" + "github.com/go-redis/redis/v9" + "github.com/go-redis/redis/extra/redisotel/v9" ) rdb := rdb.NewClient(&rdb.Options{...}) diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod index 144cf9c515..fe1a509658 100644 --- a/extra/redisotel/go.mod +++ b/extra/redisotel/go.mod @@ -1,14 +1,12 @@ -module github.com/go-redis/redis/extra/redisotel/v8 +module github.com/go-redis/redis/extra/redisotel/v9 go 1.15 -replace github.com/go-redis/redis/v8 => ../.. +replace github.com/go-redis/redis/v9 => ../.. -replace github.com/go-redis/redis/extra/rediscmd/v8 => ../rediscmd +replace github.com/go-redis/redis/extra/rediscmd/v9 => ../rediscmd require ( - github.com/go-redis/redis/extra/rediscmd/v8 v8.11.5 - github.com/go-redis/redis/v8 v8.11.5 go.opentelemetry.io/otel v1.5.0 go.opentelemetry.io/otel/sdk v1.4.1 go.opentelemetry.io/otel/trace v1.5.0 diff --git a/extra/redisotel/redisotel.go b/extra/redisotel/redisotel.go index 7015780673..53f7ec3a01 100644 --- a/extra/redisotel/redisotel.go +++ b/extra/redisotel/redisotel.go @@ -9,8 +9,8 @@ import ( semconv "go.opentelemetry.io/otel/semconv/v1.7.0" "go.opentelemetry.io/otel/trace" - "github.com/go-redis/redis/extra/rediscmd/v8" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/extra/rediscmd/v9" + "github.com/go-redis/redis/v9" ) const ( diff --git a/extra/redisotel/redisotel_test.go b/extra/redisotel/redisotel_test.go index 883dcf1734..4de0e7137f 100644 --- a/extra/redisotel/redisotel_test.go +++ b/extra/redisotel/redisotel_test.go @@ -10,8 +10,8 @@ import ( sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" - "github.com/go-redis/redis/extra/redisotel/v8" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/extra/redisotel/v9" + "github.com/go-redis/redis/v9" ) func TestNew(t *testing.T) { diff --git a/fuzz/fuzz.go b/fuzz/fuzz.go index 3225d24529..b689c75928 100644 --- a/fuzz/fuzz.go +++ b/fuzz/fuzz.go @@ -7,7 +7,7 @@ import ( "context" "time" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var ( diff --git a/go.mod b/go.mod index 36eb801071..6d5aed3f46 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/go-redis/redis/v8 +module github.com/go-redis/redis/v9 go 1.17 diff --git a/internal/hashtag/hashtag.go b/internal/hashtag/hashtag.go index b3a4f211e3..dd3c4cb800 100644 --- a/internal/hashtag/hashtag.go +++ b/internal/hashtag/hashtag.go @@ -3,7 +3,7 @@ package hashtag import ( "strings" - "github.com/go-redis/redis/v8/internal/rand" + "github.com/go-redis/redis/v9/internal/rand" ) const slotNumber = 16384 diff --git a/internal/hashtag/hashtag_test.go b/internal/hashtag/hashtag_test.go index c0b6396f91..bab55d0346 100644 --- a/internal/hashtag/hashtag_test.go +++ b/internal/hashtag/hashtag_test.go @@ -6,7 +6,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8/internal/rand" + "github.com/go-redis/redis/v9/internal/rand" ) func TestGinkgoSuite(t *testing.T) { diff --git a/internal/internal.go b/internal/internal.go index 4a59c599be..5b6474e845 100644 --- a/internal/internal.go +++ b/internal/internal.go @@ -3,7 +3,7 @@ package internal import ( "time" - "github.com/go-redis/redis/v8/internal/rand" + "github.com/go-redis/redis/v9/internal/rand" ) func RetryBackoff(retry int, minBackoff, maxBackoff time.Duration) time.Duration { diff --git a/internal/pool/bench_test.go b/internal/pool/bench_test.go index dec5d3f278..0d8dbbdf77 100644 --- a/internal/pool/bench_test.go +++ b/internal/pool/bench_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/go-redis/redis/v8/internal/pool" + "github.com/go-redis/redis/v9/internal/pool" ) type poolGetPutBenchmark struct { diff --git a/internal/pool/conn.go b/internal/pool/conn.go index 65258ec4dd..a760be2798 100644 --- a/internal/pool/conn.go +++ b/internal/pool/conn.go @@ -7,7 +7,7 @@ import ( "sync/atomic" "time" - "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v9/internal/proto" ) var noDeadline = time.Time{} diff --git a/internal/pool/pool.go b/internal/pool/pool.go index 3a6ecb27fd..42fed8e2d0 100644 --- a/internal/pool/pool.go +++ b/internal/pool/pool.go @@ -8,7 +8,7 @@ import ( "sync/atomic" "time" - "github.com/go-redis/redis/v8/internal" + "github.com/go-redis/redis/v9/internal" ) var ( diff --git a/internal/pool/pool_test.go b/internal/pool/pool_test.go index d0fbfe19c7..e1e89f44ba 100644 --- a/internal/pool/pool_test.go +++ b/internal/pool/pool_test.go @@ -10,7 +10,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8/internal/pool" + "github.com/go-redis/redis/v9/internal/pool" ) var _ = Describe("ConnPool", func() { diff --git a/internal/proto/reader.go b/internal/proto/reader.go index ac24f28a2e..1cf161a5e6 100644 --- a/internal/proto/reader.go +++ b/internal/proto/reader.go @@ -9,7 +9,7 @@ import ( "math/big" "strconv" - "github.com/go-redis/redis/v8/internal/util" + "github.com/go-redis/redis/v9/internal/util" ) // redis resp protocol data type. diff --git a/internal/proto/reader_test.go b/internal/proto/reader_test.go index 9881047bf6..ae21d463c2 100644 --- a/internal/proto/reader_test.go +++ b/internal/proto/reader_test.go @@ -5,7 +5,7 @@ import ( "io" "testing" - "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v9/internal/proto" ) func BenchmarkReader_ParseReply_Status(b *testing.B) { diff --git a/internal/proto/scan.go b/internal/proto/scan.go index 072b8e62ce..576120c54b 100644 --- a/internal/proto/scan.go +++ b/internal/proto/scan.go @@ -7,7 +7,7 @@ import ( "reflect" "time" - "github.com/go-redis/redis/v8/internal/util" + "github.com/go-redis/redis/v9/internal/util" ) // Scan parses bytes `b` to `v` with appropriate type. diff --git a/internal/proto/scan_test.go b/internal/proto/scan_test.go index 55df550b54..b3bbc515d3 100644 --- a/internal/proto/scan_test.go +++ b/internal/proto/scan_test.go @@ -6,7 +6,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v9/internal/proto" ) type testScanSliceStruct struct { diff --git a/internal/proto/writer.go b/internal/proto/writer.go index c674d44bdb..15e15989f3 100644 --- a/internal/proto/writer.go +++ b/internal/proto/writer.go @@ -8,7 +8,7 @@ import ( "strconv" "time" - "github.com/go-redis/redis/v8/internal/util" + "github.com/go-redis/redis/v9/internal/util" ) type writer interface { diff --git a/internal/proto/writer_test.go b/internal/proto/writer_test.go index 91efa01790..d71f445453 100644 --- a/internal/proto/writer_test.go +++ b/internal/proto/writer_test.go @@ -11,7 +11,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v9/internal/proto" ) type MyType struct{} diff --git a/internal/util.go b/internal/util.go index e34a7f0326..756c0b5556 100644 --- a/internal/util.go +++ b/internal/util.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/go-redis/redis/v8/internal/util" + "github.com/go-redis/redis/v9/internal/util" ) func Sleep(ctx context.Context, dur time.Duration) error { diff --git a/iterator_test.go b/iterator_test.go index 68c8b77efe..ff1d843151 100644 --- a/iterator_test.go +++ b/iterator_test.go @@ -6,7 +6,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var _ = Describe("ScanIterator", func() { diff --git a/main_test.go b/main_test.go index c52140dfc9..7a80e9d264 100644 --- a/main_test.go +++ b/main_test.go @@ -15,7 +15,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) const ( diff --git a/options.go b/options.go index bea7efbfb0..99cfddbbaf 100644 --- a/options.go +++ b/options.go @@ -13,7 +13,7 @@ import ( "strings" "time" - "github.com/go-redis/redis/v8/internal/pool" + "github.com/go-redis/redis/v9/internal/pool" ) // Limiter is the interface of a rate limiter or a circuit breaker. diff --git a/pipeline_test.go b/pipeline_test.go index f24114d72a..b6fc5bb96f 100644 --- a/pipeline_test.go +++ b/pipeline_test.go @@ -6,7 +6,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var _ = Describe("pipelining", func() { diff --git a/pool_test.go b/pool_test.go index 7be2ced705..a45b3de4be 100644 --- a/pool_test.go +++ b/pool_test.go @@ -7,7 +7,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var _ = Describe("pool", func() { diff --git a/pubsub.go b/pubsub.go index 3df2d65df9..75e5097b0b 100644 --- a/pubsub.go +++ b/pubsub.go @@ -7,9 +7,9 @@ import ( "sync" "time" - "github.com/go-redis/redis/v8/internal" - "github.com/go-redis/redis/v8/internal/pool" - "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v9/internal" + "github.com/go-redis/redis/v9/internal/pool" + "github.com/go-redis/redis/v9/internal/proto" ) // PubSub implements Pub/Sub commands as described in diff --git a/pubsub_test.go b/pubsub_test.go index 5776bbde43..6777ec67ea 100644 --- a/pubsub_test.go +++ b/pubsub_test.go @@ -9,7 +9,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var _ = Describe("PubSub", func() { diff --git a/race_test.go b/race_test.go index 34699d1327..6e4ab4419a 100644 --- a/race_test.go +++ b/race_test.go @@ -13,7 +13,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var _ = Describe("races", func() { diff --git a/redis.go b/redis.go index 8320669edf..7248057d2c 100644 --- a/redis.go +++ b/redis.go @@ -7,9 +7,9 @@ import ( "sync/atomic" "time" - "github.com/go-redis/redis/v8/internal" - "github.com/go-redis/redis/v8/internal/pool" - "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v9/internal" + "github.com/go-redis/redis/v9/internal/pool" + "github.com/go-redis/redis/v9/internal/proto" ) // Nil reply returned by Redis when key does not exist. diff --git a/redis_test.go b/redis_test.go index 2215228f73..af721fe74c 100644 --- a/redis_test.go +++ b/redis_test.go @@ -11,7 +11,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) type redisHookError struct { diff --git a/ring.go b/ring.go index 8309cbe4e9..21a9264946 100644 --- a/ring.go +++ b/ring.go @@ -14,10 +14,10 @@ import ( "github.com/cespare/xxhash/v2" rendezvous "github.com/dgryski/go-rendezvous" //nolint - "github.com/go-redis/redis/v8/internal" - "github.com/go-redis/redis/v8/internal/hashtag" - "github.com/go-redis/redis/v8/internal/pool" - "github.com/go-redis/redis/v8/internal/rand" + "github.com/go-redis/redis/v9/internal" + "github.com/go-redis/redis/v9/internal/hashtag" + "github.com/go-redis/redis/v9/internal/pool" + "github.com/go-redis/redis/v9/internal/rand" ) var errRingShardsDown = errors.New("redis: all ring shards are down") diff --git a/ring_test.go b/ring_test.go index b0705c5b8a..50b13ffde2 100644 --- a/ring_test.go +++ b/ring_test.go @@ -12,7 +12,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var _ = Describe("Redis Ring", func() { diff --git a/sentinel.go b/sentinel.go index e133d7a069..5cec0c5398 100644 --- a/sentinel.go +++ b/sentinel.go @@ -9,9 +9,9 @@ import ( "sync" "time" - "github.com/go-redis/redis/v8/internal" - "github.com/go-redis/redis/v8/internal/pool" - "github.com/go-redis/redis/v8/internal/rand" + "github.com/go-redis/redis/v9/internal" + "github.com/go-redis/redis/v9/internal/pool" + "github.com/go-redis/redis/v9/internal/rand" ) //------------------------------------------------------------------------------ diff --git a/sentinel_test.go b/sentinel_test.go index d0fa9c959a..ecde161f67 100644 --- a/sentinel_test.go +++ b/sentinel_test.go @@ -6,7 +6,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var _ = Describe("Sentinel", func() { diff --git a/tx.go b/tx.go index 8c9d87202a..079149fb1e 100644 --- a/tx.go +++ b/tx.go @@ -3,8 +3,8 @@ package redis import ( "context" - "github.com/go-redis/redis/v8/internal/pool" - "github.com/go-redis/redis/v8/internal/proto" + "github.com/go-redis/redis/v9/internal/pool" + "github.com/go-redis/redis/v9/internal/proto" ) // TxFailedErr transaction redis failed. diff --git a/tx_test.go b/tx_test.go index 030a56cc6b..ed55518b01 100644 --- a/tx_test.go +++ b/tx_test.go @@ -8,7 +8,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var _ = Describe("Tx", func() { diff --git a/universal_test.go b/universal_test.go index 7491a1d1dd..15cb7c8162 100644 --- a/universal_test.go +++ b/universal_test.go @@ -4,7 +4,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/go-redis/redis/v8" + "github.com/go-redis/redis/v9" ) var _ = Describe("UniversalClient", func() { From 98300d72b9e54e1954182f62acb5bee8d60a1ebe Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 18:00:44 +0300 Subject: [PATCH 041/621] chore: cleanup --- example/del-keys-without-ttl/go.mod | 2 -- example/hll/go.mod | 2 -- example/lua-scripting/go.mod | 2 -- example/redis-bloom/go.mod | 2 -- example/scan-struct/go.mod | 1 - 5 files changed, 9 deletions(-) diff --git a/example/del-keys-without-ttl/go.mod b/example/del-keys-without-ttl/go.mod index 435f636e77..11e562a651 100644 --- a/example/del-keys-without-ttl/go.mod +++ b/example/del-keys-without-ttl/go.mod @@ -3,5 +3,3 @@ module github.com/go-redis/redis/example/del-keys-without-ttl go 1.14 replace github.com/go-redis/redis/v9 => ../.. - -require github.com/go-redis/redis/v9 v8.11.5 diff --git a/example/hll/go.mod b/example/hll/go.mod index 42800bcd02..9e002ee4c1 100644 --- a/example/hll/go.mod +++ b/example/hll/go.mod @@ -3,5 +3,3 @@ module github.com/go-redis/redis/example/hll go 1.14 replace github.com/go-redis/redis/v9 => ../.. - -require github.com/go-redis/redis/v9 v8.11.5 diff --git a/example/lua-scripting/go.mod b/example/lua-scripting/go.mod index d30d832872..41987051d8 100644 --- a/example/lua-scripting/go.mod +++ b/example/lua-scripting/go.mod @@ -3,5 +3,3 @@ module github.com/go-redis/redis/example/redis-bloom go 1.14 replace github.com/go-redis/redis/v9 => ../.. - -require github.com/go-redis/redis/v9 v8.11.5 diff --git a/example/redis-bloom/go.mod b/example/redis-bloom/go.mod index d30d832872..41987051d8 100644 --- a/example/redis-bloom/go.mod +++ b/example/redis-bloom/go.mod @@ -3,5 +3,3 @@ module github.com/go-redis/redis/example/redis-bloom go 1.14 replace github.com/go-redis/redis/v9 => ../.. - -require github.com/go-redis/redis/v9 v8.11.5 diff --git a/example/scan-struct/go.mod b/example/scan-struct/go.mod index 40a2930929..93cabbd695 100644 --- a/example/scan-struct/go.mod +++ b/example/scan-struct/go.mod @@ -6,5 +6,4 @@ replace github.com/go-redis/redis/v9 => ../.. require ( github.com/davecgh/go-spew v1.1.1 - github.com/go-redis/redis/v9 v8.11.5 ) From 58e087fe08616c3ceb75c69c37ec0287e45a2042 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 18:02:11 +0300 Subject: [PATCH 042/621] chore: release v9.0.0-beta.1 (release.sh) --- CHANGELOG.md | 25 ++ example/del-keys-without-ttl/go.mod | 2 + example/del-keys-without-ttl/go.sum | 16 +- example/hll/go.mod | 2 + example/hll/go.sum | 16 +- example/lua-scripting/go.mod | 2 + example/lua-scripting/go.sum | 16 +- example/otel/go.mod | 15 +- example/otel/go.sum | 417 +++++++++++++++++++++++----- example/redis-bloom/go.mod | 2 + example/redis-bloom/go.sum | 16 +- example/scan-struct/go.mod | 1 + example/scan-struct/go.sum | 16 +- extra/rediscensus/go.mod | 2 + extra/rediscensus/go.sum | 16 +- extra/rediscmd/go.mod | 3 +- extra/rediscmd/go.sum | 16 +- extra/redisotel/go.mod | 6 +- extra/redisotel/go.sum | 30 +- package.json | 2 +- version.go | 2 +- 21 files changed, 484 insertions(+), 139 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab9e7d859a..4377e94551 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,28 @@ +# [9.0.0-beta.1](https://github.com/go-redis/redis/compare/v8.11.5...v9.0.0-beta.1) (2022-06-04) + + +### Bug Fixes + +* **#1943:** xInfoConsumer.Idle should be time.Duration instead of int64 ([#2052](https://github.com/go-redis/redis/issues/2052)) ([997ab5e](https://github.com/go-redis/redis/commit/997ab5e7e3ddf53837917013a4babbded73e944f)), closes [#1943](https://github.com/go-redis/redis/issues/1943) +* add XInfoConsumers test ([6f1a1ac](https://github.com/go-redis/redis/commit/6f1a1ac284ea3f683eeb3b06a59969e8424b6376)) +* fix tests ([3a722be](https://github.com/go-redis/redis/commit/3a722be81180e4d2a9cf0a29dc9a1ee1421f5859)) +* remove test(XInfoConsumer.idle), not a stable return value when tested. ([f5fbb36](https://github.com/go-redis/redis/commit/f5fbb367e7d9dfd7f391fc535a7387002232fa8a)) +* update ChannelWithSubscriptions to accept options ([c98c5f0](https://github.com/go-redis/redis/commit/c98c5f0eebf8d254307183c2ce702a48256b718d)) +* update COMMAND parser for Redis 7 ([b0bb514](https://github.com/go-redis/redis/commit/b0bb514059249e01ed7328c9094e5b8a439dfb12)) +* use redis over ssh channel([#2057](https://github.com/go-redis/redis/issues/2057)) ([#2060](https://github.com/go-redis/redis/issues/2060)) ([3961b95](https://github.com/go-redis/redis/commit/3961b9577f622a3079fe74f8fc8da12ba67a77ff)) + + +### Features + +* add ClientUnpause ([91171f5](https://github.com/go-redis/redis/commit/91171f5e19a261dc4cfbf8706626d461b6ba03e4)) +* add NewXPendingResult for unit testing XPending ([#2066](https://github.com/go-redis/redis/issues/2066)) ([b7fd09e](https://github.com/go-redis/redis/commit/b7fd09e59479bc6ed5b3b13c4645a3620fd448a3)) +* add WriteArg and Scan net.IP([#2062](https://github.com/go-redis/redis/issues/2062)) ([7d5167e](https://github.com/go-redis/redis/commit/7d5167e8624ac1515e146ed183becb97dadb3d1a)) +* **pool:** add check for badConnection ([a8a7665](https://github.com/go-redis/redis/commit/a8a7665ddf8cc657c5226b1826a8ee83dab4b8c1)), closes [#2053](https://github.com/go-redis/redis/issues/2053) +* provide a username and password callback method, so that the plaintext username and password will not be stored in the memory, and the username and password will only be generated once when the CredentialsProvider is called. After the method is executed, the username and password strings on the stack will be released. ([#2097](https://github.com/go-redis/redis/issues/2097)) ([56a3dbc](https://github.com/go-redis/redis/commit/56a3dbc7b656525eb88e0735e239d56e04a23bee)) +* upgrade to Redis 7 ([d09c27e](https://github.com/go-redis/redis/commit/d09c27e6046129fd27b1d275e5a13a477bd7f778)) + + + ## v9 UNRELEASED - Added support for [RESP3](https://github.com/antirez/RESP3/blob/master/spec.md) protocol. diff --git a/example/del-keys-without-ttl/go.mod b/example/del-keys-without-ttl/go.mod index 11e562a651..4a10f38314 100644 --- a/example/del-keys-without-ttl/go.mod +++ b/example/del-keys-without-ttl/go.mod @@ -3,3 +3,5 @@ module github.com/go-redis/redis/example/del-keys-without-ttl go 1.14 replace github.com/go-redis/redis/v9 => ../.. + +require github.com/go-redis/redis/v9 v9.0.0-beta.1 diff --git a/example/del-keys-without-ttl/go.sum b/example/del-keys-without-ttl/go.sum index 142b2afe28..f694e5247c 100644 --- a/example/del-keys-without-ttl/go.sum +++ b/example/del-keys-without-ttl/go.sum @@ -37,13 +37,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -57,8 +57,9 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -74,13 +75,16 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/example/hll/go.mod b/example/hll/go.mod index 9e002ee4c1..87d9eab4a6 100644 --- a/example/hll/go.mod +++ b/example/hll/go.mod @@ -3,3 +3,5 @@ module github.com/go-redis/redis/example/hll go 1.14 replace github.com/go-redis/redis/v9 => ../.. + +require github.com/go-redis/redis/v9 v9.0.0-beta.1 diff --git a/example/hll/go.sum b/example/hll/go.sum index 142b2afe28..f694e5247c 100644 --- a/example/hll/go.sum +++ b/example/hll/go.sum @@ -37,13 +37,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -57,8 +57,9 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -74,13 +75,16 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/example/lua-scripting/go.mod b/example/lua-scripting/go.mod index 41987051d8..7d25def773 100644 --- a/example/lua-scripting/go.mod +++ b/example/lua-scripting/go.mod @@ -3,3 +3,5 @@ module github.com/go-redis/redis/example/redis-bloom go 1.14 replace github.com/go-redis/redis/v9 => ../.. + +require github.com/go-redis/redis/v9 v9.0.0-beta.1 diff --git a/example/lua-scripting/go.sum b/example/lua-scripting/go.sum index 142b2afe28..f694e5247c 100644 --- a/example/lua-scripting/go.sum +++ b/example/lua-scripting/go.sum @@ -37,13 +37,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -57,8 +57,9 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -74,13 +75,16 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/example/otel/go.mod b/example/otel/go.mod index 1203d9e9ab..f658e652be 100644 --- a/example/otel/go.mod +++ b/example/otel/go.mod @@ -9,10 +9,13 @@ replace github.com/go-redis/redis/extra/redisotel/v9 => ../../extra/redisotel replace github.com/go-redis/redis/extra/rediscmd/v9 => ../../extra/rediscmd require ( - github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.10 - go.opentelemetry.io/otel v1.5.0 - go.opentelemetry.io/otel/exporters/jaeger v1.5.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.5.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.5.0 // indirect - golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf // indirect + github.com/go-redis/redis/extra/rediscmd/v9 v9.0.0-beta.1 // indirect + github.com/go-redis/redis/extra/redisotel/v9 v9.0.0-beta.1 + github.com/go-redis/redis/v9 v9.0.0-beta.1 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3 // indirect + github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.14 + go.opentelemetry.io/otel v1.7.0 + golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect + google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8 // indirect + google.golang.org/grpc v1.47.0 // indirect ) diff --git a/example/otel/go.sum b/example/otel/go.sum index 4c41bc4036..f3598e0761 100644 --- a/example/otel/go.sum +++ b/example/otel/go.sum @@ -1,12 +1,47 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= -github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -17,8 +52,10 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -29,22 +66,42 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -56,21 +113,49 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.0/go.mod h1:XnLCLFp3tjoZJszVKjfpyAK6J8sYIcQXWQxmqLWF21I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.2/go.mod h1:chrfS3YoLAlKTRE5cFWvCbt8uGAjshktT4PveTUpsFQ= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3 h1:BGNSrTRW4rwfhJiFwvwF4XQ0Y72Jj9YEgxVrtovbD5o= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3/go.mod h1:VHn7KgNsRriXa4mcgtkpR00OXyQY6g67JWMvn+R27A4= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= @@ -85,90 +170,109 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.10 h1:STSRpcp18xb6huePD0yj4uiUFd1cOdb2xexhhPNWwCo= -github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.10/go.mod h1:7UDvwITVMKhXZGmxKa/lJujNIOKb5ReIRAVwwrc60bI= -github.com/uptrace/uptrace-go v1.4.0 h1:WPYpiCi84nSAXVdtZQamcmDnTZz9724EONo8v1ud9/0= -github.com/uptrace/uptrace-go v1.4.0/go.mod h1:KAPqyJuSaRA6YOea6UZEuSeXtWap92Qws9rPYNW8GhU= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.14 h1:De0aL20N/6OKEhVriq+emXsETL0ZuAEXNlz74O5aTD0= +github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.14/go.mod h1:XZvp41aATsghUfehYGsi2/nEY2BmwgWU9QpXnQvqbR8= +github.com/uptrace/uptrace-go v1.7.1 h1:08V74pATGYoJK+t94oRH6fdaLhs+r8rGWZOk4U6Yl40= +github.com/uptrace/uptrace-go v1.7.1/go.mod h1:ZEFBLqjLJplFeak8w4IrpzDtXd+dY8QhCyHHCL6VP90= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.opentelemetry.io/contrib/instrumentation/runtime v0.27.0/go.mod h1:6ZYYPfSKyhnkpw3xOssb1PMclnNs8dnSzO5POa+02ys= -go.opentelemetry.io/contrib/instrumentation/runtime v0.29.0 h1:ZnLxB76QjHDLnrUWLYgcCc8lcdRGoraTLvJEWmwwC80= -go.opentelemetry.io/contrib/instrumentation/runtime v0.29.0/go.mod h1:qGVpMUNpULYYXRYCQB3DNUe+of22Y+M28i1Oke8SuKQ= -go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I= -go.opentelemetry.io/otel v1.4.0/go.mod h1:jeAqMFKy2uLIxCtKxoFj0FAL5zAPKQagc3+GtBWakzk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/contrib/instrumentation/runtime v0.32.0 h1:eMQf85EgNd2YWEikRJwEy4ADOiwlIum4rcHcssB4Qzk= +go.opentelemetry.io/contrib/instrumentation/runtime v0.32.0/go.mod h1:qtaLlIO4HC4DfedkYTOrvS2u7nA3N/v8w9mehrBD4O8= go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4= -go.opentelemetry.io/otel v1.5.0 h1:DhCU8oR2sJH9rfnwPdoV/+BJ7UIN5kXHL8DuSGrPU8E= -go.opentelemetry.io/otel v1.5.0/go.mod h1:Jm/m+rNp/z0eqJc74H7LPwQ3G87qkU/AnnAydAjSAHk= -go.opentelemetry.io/otel/exporters/jaeger v1.4.1/go.mod h1:ZW7vkOu9nC1CxsD8bHNHCia5JUbwP39vxgd1q4Z5rCI= -go.opentelemetry.io/otel/exporters/jaeger v1.5.0 h1:ZR7nhLSfLufS5AHk/iN11Q+W9XYwsJrVZ1Frb833d+Y= -go.opentelemetry.io/otel/exporters/jaeger v1.5.0/go.mod h1:rSeUArMBRe1eQLo1T0WxOazohN1M2mYThWJQmn1BjRQ= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0 h1:lC0ldaVQwBpO1G5IaOYRbBCa67h6ioGkK6qYkqZbYOI= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.5.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.27.0 h1:t1aPfMj5oZzv2EaRmdC2QPQg1a7MaBjraOh4Hjwuia8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.27.0/go.mod h1:aZnoYVx7GIuMROciGC3cjZhYxMD/lKroRJUnFY0afu0= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.27.0 h1:RJURCSrqUjJiCY3GuFCVP2EPKOQLwNXQ4FI3aH2KoHg= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.27.0/go.mod h1:LIc1eCpkU94tPnXxH40ya41Oyxm7sL+oDvxCYPFpnV8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.0/go.mod h1:3oS+j2WUoJVyj6/BzQN/52G17lNJDulngsOxDm1w2PY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1/go.mod h1:o5RW5o2pKpJLD5dNTCmjF1DorYwMeFJmb/rKr5sLaa8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.5.0 h1:Arn+HOtC6neocvr6J4ykfILvtiSwoDkkLFMaVLFKBnY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.5.0/go.mod h1:VoN81wyy6jVVCzHImh8S+IYhw+oAUj6XgEsTkP8DyrQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.0/go.mod h1:ew1NcwkHo0QFT3uTm3m2IVZMkZdVIpbOYNPasgWwpdk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1/go.mod h1:c6E4V3/U+miqjs/8l950wggHGL1qzlp0Ypj9xoGrPqo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.5.0 h1:dOXExSS490NJaVZD496oIK2Z22S1JQnOsrrMh/p/mLU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.5.0/go.mod h1:Es/Ag4ORtjwWCRjS0aEXgmxB5VqKQlnp481/P5aZyPQ= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.0/go.mod h1:TqC+Li5O2V5hRWq4TkIx0oHFu/McCi/KAVGBaKkhU5Q= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.4.1/go.mod h1:BFiGsTMZdqtxufux8ANXuMeRz9dMPVFdJZadUWDFD7o= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.5.0 h1:/Lu2JuL9Mb+B+kSv/RsDMgA/5FaBaxfyfMnICFepiBs= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.5.0/go.mod h1:5gUXICq93HyDh8Rij7p8ilJEC1Sqk0u3lSGs62i8hJQ= -go.opentelemetry.io/otel/internal/metric v0.25.0/go.mod h1:Nhuw26QSX7d6n4duoqAFi5KOQR4AuzyMcl5eXOgwxtc= -go.opentelemetry.io/otel/internal/metric v0.27.0 h1:9dAVGAfFiiEq5NVB9FUJ5et+btbDQAUIJehJ+ikyryk= -go.opentelemetry.io/otel/internal/metric v0.27.0/go.mod h1:n1CVxRqKqYZtqyTh9U/onvKapPGv7y/rpyOTI+LFNzw= -go.opentelemetry.io/otel/metric v0.25.0/go.mod h1:E884FSpQfnJOMMUaq+05IWlJ4rjZpk2s/F1Ju+TEEm8= -go.opentelemetry.io/otel/metric v0.27.0 h1:HhJPsGhJoKRSegPQILFbODU56NS/L1UE4fS1sC5kIwQ= -go.opentelemetry.io/otel/metric v0.27.0/go.mod h1:raXDJ7uP2/Jc0nVZWQjJtzoyssOYWu/+pjZqRzfvZ7g= -go.opentelemetry.io/otel/sdk v1.4.0/go.mod h1:71GJPNJh4Qju6zJuYl1CrYtXbrgfau/M9UAggqiy1UE= +go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= +go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= +go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= +go.opentelemetry.io/otel/exporters/jaeger v1.7.0/go.mod h1:PwQAOqBgqbLQRKlj466DuD2qyMjbtcPpfPfj+AqbSBs= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 h1:7Yxsak1q4XrJ5y7XBnNwqWx9amMZvoidCctv62XOQ6Y= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0/go.mod h1:M1hVZHNxcbkAlcvrOMlpQ4YOO3Awf+4N2dxkZL3xm04= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.30.0 h1:Os0ds8fJp2AUa9DNraFWIycgUzevz47i6UvnSh+8LQ0= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.30.0/go.mod h1:8Lz1GGcrx1kPGE3zqDrK7ZcPzABEfIQqBjq7roQa5ZA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.30.0 h1:7E8znQuiqnaFDDl1zJYUpoqHteZI6u2rrcxH3Gwoiis= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.30.0/go.mod h1:RejW0QAFotPIixlFZKZka4/70S5UaFOqDO9DYOgScIs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 h1:cMDtmgJ5FpRvqx9x2Aq+Mm0O6K/zcUkH73SFz20TuBw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0/go.mod h1:ceUgdyfNv4h4gLxHR0WNfDiiVmZFodZhZSbOLhpxqXE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 h1:MFAyzUPrTwLOwCi+cltN0ZVyy4phU41lwH+lyMyQTS4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0/go.mod h1:E+/KKhwOSw8yoPxSSuUHG6vKppkvhN+S1Jc7Nib3k3o= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 h1:8hPcgCg0rUJiKE6VWahRvjgLUrNl7rW2hffUEPKXVEM= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0/go.mod h1:K4GDXPY6TjUiwbOh+DkKaEdCF8y+lvMoM6SeAPyfCCM= +go.opentelemetry.io/otel/metric v0.30.0 h1:Hs8eQZ8aQgs0U49diZoaS6Uaxw3+bBE3lcMUKBFIk3c= +go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU= go.opentelemetry.io/otel/sdk v1.4.1/go.mod h1:NBwHDgDIBYjwK2WNu1OPgsIc2IJzmBXNnvIJxJc8BpE= -go.opentelemetry.io/otel/sdk v1.5.0 h1:QKhWBbcOC9fDCZKCfPFjWTWpfIlJR+i9xiUDYrLVmZs= -go.opentelemetry.io/otel/sdk v1.5.0/go.mod h1:CU4J1v+7iEljnm1G14QjdFWOXUyYLHVh0Lh+/BTYyFg= -go.opentelemetry.io/otel/sdk/metric v0.27.0 h1:CDEu96Js5IP7f4bJ8eimxF09V5hKYmE7CeyKSjmAL1s= -go.opentelemetry.io/otel/sdk/metric v0.27.0/go.mod h1:lOgrT5C3ORdbqp2LsDrx+pBj6gbZtQ5Omk27vH3EaW0= -go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0= -go.opentelemetry.io/otel/trace v1.4.0/go.mod h1:uc3eRsqDfWs9R7b92xbQbU42/eTNz4N+gLP8qJCi4aE= +go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= +go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= +go.opentelemetry.io/otel/sdk/metric v0.30.0 h1:XTqQ4y3erR2Oj8xSAOL5ovO5011ch2ELg51z4fVkpME= +go.opentelemetry.io/otel/sdk/metric v0.30.0/go.mod h1:8AKFRi5HyvTR0RRty3paN1aMC9HMT+NzcEhw/BLkLX8= go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc= -go.opentelemetry.io/otel/trace v1.5.0 h1:AKQZ9zJsBRFAp7zLdyGNkqG2rToCDIt3i5tcLzQlbmU= -go.opentelemetry.io/otel/trace v1.5.0/go.mod h1:sq55kfhjXYr1zVSyexg0w1mpa03AYXR5eyTkB9NPPdE= +go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= +go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.12.0 h1:CMJ/3Wp7iOWES+CYLfnBv+DVmPbB+kmy9PJ92XvlR6c= -go.opentelemetry.io/proto/otlp v0.12.0/go.mod h1:TsIjwGWIx5VFYv9KGVlOpxoBl5Dy+63SUguV7GGvlSQ= +go.opentelemetry.io/proto/otlp v0.16.0 h1:WHzDWdXUvbc5bG2ObdrGfaNpQz7ft7QN9HHmJlbiB1E= +go.opentelemetry.io/proto/otlp v0.16.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -179,59 +283,150 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= +golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf h1:Fm4IcnUL803i92qDlmB0obyHmosDrxZWxJL3gIeNqOw= -golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -240,25 +435,86 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106 h1:ErU+UA6wxadoU8nWrsy5MZUVBs75K17zUCsUCIfrXCE= -google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To= +google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8 h1:qRu95HZ148xXw+XeZ3dvqe85PxH4X8+jIo0iRPKcEnM= +google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -267,15 +523,18 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -285,7 +544,17 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/example/redis-bloom/go.mod b/example/redis-bloom/go.mod index 41987051d8..7d25def773 100644 --- a/example/redis-bloom/go.mod +++ b/example/redis-bloom/go.mod @@ -3,3 +3,5 @@ module github.com/go-redis/redis/example/redis-bloom go 1.14 replace github.com/go-redis/redis/v9 => ../.. + +require github.com/go-redis/redis/v9 v9.0.0-beta.1 diff --git a/example/redis-bloom/go.sum b/example/redis-bloom/go.sum index 142b2afe28..f694e5247c 100644 --- a/example/redis-bloom/go.sum +++ b/example/redis-bloom/go.sum @@ -37,13 +37,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -57,8 +57,9 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -74,13 +75,16 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/example/scan-struct/go.mod b/example/scan-struct/go.mod index 93cabbd695..761414a490 100644 --- a/example/scan-struct/go.mod +++ b/example/scan-struct/go.mod @@ -6,4 +6,5 @@ replace github.com/go-redis/redis/v9 => ../.. require ( github.com/davecgh/go-spew v1.1.1 + github.com/go-redis/redis/v9 v9.0.0-beta.1 ) diff --git a/example/scan-struct/go.sum b/example/scan-struct/go.sum index f3be7f1926..e14c74224a 100644 --- a/example/scan-struct/go.sum +++ b/example/scan-struct/go.sum @@ -38,13 +38,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -58,8 +58,9 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -75,13 +76,16 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/extra/rediscensus/go.mod b/extra/rediscensus/go.mod index 1a7f808029..bc58127b11 100644 --- a/extra/rediscensus/go.mod +++ b/extra/rediscensus/go.mod @@ -7,6 +7,8 @@ replace github.com/go-redis/redis/v9 => ../.. replace github.com/go-redis/redis/extra/rediscmd/v9 => ../rediscmd require ( + github.com/go-redis/redis/extra/rediscmd/v9 v9.0.0-beta.1 + github.com/go-redis/redis/v9 v9.0.0-beta.1 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect go.opencensus.io v0.23.0 ) diff --git a/extra/rediscensus/go.sum b/extra/rediscensus/go.sum index 5bfa139c56..2cc377b3a2 100644 --- a/extra/rediscensus/go.sum +++ b/extra/rediscensus/go.sum @@ -58,13 +58,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -91,8 +91,9 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -111,13 +112,16 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/extra/rediscmd/go.mod b/extra/rediscmd/go.mod index f600c19cb5..48b73744f2 100644 --- a/extra/rediscmd/go.mod +++ b/extra/rediscmd/go.mod @@ -5,6 +5,7 @@ go 1.15 replace github.com/go-redis/redis/v9 => ../.. require ( + github.com/go-redis/redis/v9 v9.0.0-beta.1 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.18.1 + github.com/onsi/gomega v1.19.0 ) diff --git a/extra/rediscmd/go.sum b/extra/rediscmd/go.sum index 142b2afe28..f694e5247c 100644 --- a/extra/rediscmd/go.sum +++ b/extra/rediscmd/go.sum @@ -37,13 +37,13 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -57,8 +57,9 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -74,13 +75,16 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod index fe1a509658..96d48ee66f 100644 --- a/extra/redisotel/go.mod +++ b/extra/redisotel/go.mod @@ -7,7 +7,9 @@ replace github.com/go-redis/redis/v9 => ../.. replace github.com/go-redis/redis/extra/rediscmd/v9 => ../rediscmd require ( - go.opentelemetry.io/otel v1.5.0 + github.com/go-redis/redis/extra/rediscmd/v9 v9.0.0-beta.1 + github.com/go-redis/redis/v9 v9.0.0-beta.1 + go.opentelemetry.io/otel v1.7.0 go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.5.0 + go.opentelemetry.io/otel/trace v1.7.0 ) diff --git a/extra/redisotel/go.sum b/extra/redisotel/go.sum index 1bcf1e7f33..6521762e47 100644 --- a/extra/redisotel/go.sum +++ b/extra/redisotel/go.sum @@ -11,8 +11,9 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -43,28 +44,29 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4= -go.opentelemetry.io/otel v1.5.0 h1:DhCU8oR2sJH9rfnwPdoV/+BJ7UIN5kXHL8DuSGrPU8E= -go.opentelemetry.io/otel v1.5.0/go.mod h1:Jm/m+rNp/z0eqJc74H7LPwQ3G87qkU/AnnAydAjSAHk= +go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= +go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= go.opentelemetry.io/otel/sdk v1.4.1 h1:J7EaW71E0v87qflB4cDolaqq3AcujGrtyIPGQoZOB0Y= go.opentelemetry.io/otel/sdk v1.4.1/go.mod h1:NBwHDgDIBYjwK2WNu1OPgsIc2IJzmBXNnvIJxJc8BpE= go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc= -go.opentelemetry.io/otel/trace v1.5.0 h1:AKQZ9zJsBRFAp7zLdyGNkqG2rToCDIt3i5tcLzQlbmU= -go.opentelemetry.io/otel/trace v1.5.0/go.mod h1:sq55kfhjXYr1zVSyexg0w1mpa03AYXR5eyTkB9NPPdE= +go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= +go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -74,8 +76,9 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -92,13 +95,16 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= diff --git a/package.json b/package.json index e4ea4bb074..8ff0ef68d2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redis", - "version": "8.11.5", + "version": "9.0.0-beta.1", "main": "index.js", "repository": "git@github.com:go-redis/redis.git", "author": "Vladimir Mihailenco ", diff --git a/version.go b/version.go index 112c9a2da0..e08b7407d2 100644 --- a/version.go +++ b/version.go @@ -2,5 +2,5 @@ package redis // Version is the current release version. func Version() string { - return "8.11.5" + return "9.0.0-beta.1" } From 0768a688c6881b4988857c9eaa2841a8690d3eec Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sat, 4 Jun 2022 18:20:41 +0300 Subject: [PATCH 043/621] chore: update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bb2ebcca67..468cf10b79 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ If you are using **Redis 6**, install go-redis/**v8**: go get github.com/go-redis/redis/v8 ``` -If you are using **Redis 7**, install **go-redis/v9**: +If you are using **Redis 7**, install go-redis/**v9**: ```shell go get github.com/go-redis/redis/v9 From 4ddd7d18036f93ac0753e1905c7dbd17cde3ca58 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Sun, 5 Jun 2022 09:58:05 +0300 Subject: [PATCH 044/621] chore: remove WithContext --- bench_test.go | 45 --------------------------------------------- cluster.go | 21 ++------------------- cluster_test.go | 8 -------- pipeline.go | 1 - race_test.go | 7 ------- redis.go | 17 ----------------- ring.go | 17 ----------------- sentinel.go | 15 --------------- tx.go | 17 ----------------- universal.go | 1 - 10 files changed, 2 insertions(+), 147 deletions(-) diff --git a/bench_test.go b/bench_test.go index 4af5184253..5ddd82e44c 100644 --- a/bench_test.go +++ b/bench_test.go @@ -273,36 +273,6 @@ func BenchmarkXRead(b *testing.B) { }) } -var clientSink *redis.Client - -func BenchmarkWithContext(b *testing.B) { - ctx := context.Background() - rdb := benchmarkRedisClient(ctx, 10) - defer rdb.Close() - - b.ResetTimer() - b.ReportAllocs() - - for i := 0; i < b.N; i++ { - clientSink = rdb.WithContext(ctx) - } -} - -var ringSink *redis.Ring - -func BenchmarkRingWithContext(b *testing.B) { - ctx := context.Background() - rdb := redis.NewRing(&redis.RingOptions{}) - defer rdb.Close() - - b.ResetTimer() - b.ReportAllocs() - - for i := 0; i < b.N; i++ { - ringSink = rdb.WithContext(ctx) - } -} - //------------------------------------------------------------------------------ func newClusterScenario() *clusterScenario { @@ -395,18 +365,3 @@ func BenchmarkClusterSetString(b *testing.B) { } }) } - -var clusterSink *redis.ClusterClient - -func BenchmarkClusterWithContext(b *testing.B) { - ctx := context.Background() - rdb := redis.NewClusterClient(&redis.ClusterOptions{}) - defer rdb.Close() - - b.ResetTimer() - b.ReportAllocs() - - for i := 0; i < b.N; i++ { - clusterSink = rdb.WithContext(ctx) - } -} diff --git a/cluster.go b/cluster.go index b3e7a8cd35..e3a344fcb3 100644 --- a/cluster.go +++ b/cluster.go @@ -723,21 +723,6 @@ func NewClusterClient(opt *ClusterOptions) *ClusterClient { return c } -func (c *ClusterClient) Context() context.Context { - return c.ctx -} - -func (c *ClusterClient) WithContext(ctx context.Context) *ClusterClient { - if ctx == nil { - panic("nil context") - } - clone := *c - clone.cmdable = clone.Process - clone.hooks.lock() - clone.ctx = ctx - return &clone -} - // Options returns read-only Options that were used to create the client. func (c *ClusterClient) Options() *ClusterOptions { return c.opt @@ -1069,7 +1054,7 @@ func (c *ClusterClient) reaper(idleCheckFrequency time.Duration) { for _, node := range nodes { _, err := node.Client.connPool.(*pool.ConnPool).ReapStaleConns() if err != nil { - internal.Logger.Printf(c.Context(), "ReapStaleConns failed: %s", err) + internal.Logger.Printf(context.TODO(), "ReapStaleConns failed: %s", err) } } } @@ -1077,7 +1062,6 @@ func (c *ClusterClient) reaper(idleCheckFrequency time.Duration) { func (c *ClusterClient) Pipeline() Pipeliner { pipe := Pipeline{ - ctx: c.ctx, exec: c.processPipeline, } pipe.init() @@ -1259,7 +1243,6 @@ func (c *ClusterClient) checkMovedErr( // TxPipeline acts like Pipeline, but wraps queued commands with MULTI/EXEC. func (c *ClusterClient) TxPipeline() Pipeliner { pipe := Pipeline{ - ctx: c.ctx, exec: c.processTxPipeline, } pipe.init() @@ -1616,7 +1599,7 @@ func (c *ClusterClient) cmdInfo(name string) *CommandInfo { info := cmdsInfo[name] if info == nil { - internal.Logger.Printf(c.Context(), "info for cmd=%s not found", name) + internal.Logger.Printf(context.TODO(), "info for cmd=%s not found", name) } return info } diff --git a/cluster_test.go b/cluster_test.go index 59fcef2f30..42f95fbd9d 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -237,14 +237,6 @@ var _ = Describe("ClusterClient", func() { var client *redis.ClusterClient assertClusterClient := func() { - It("supports WithContext", func() { - ctx, cancel := context.WithCancel(ctx) - cancel() - - err := client.Ping(ctx).Err() - Expect(err).To(MatchError("context canceled")) - }) - It("should GET/SET/DEL", func() { err := client.Get(ctx, "A").Err() Expect(err).To(Equal(redis.Nil)) diff --git a/pipeline.go b/pipeline.go index b9845ba33e..52bd7213cc 100644 --- a/pipeline.go +++ b/pipeline.go @@ -38,7 +38,6 @@ type Pipeline struct { cmdable statefulCmdable - ctx context.Context exec pipelineExecer mu sync.Mutex diff --git a/race_test.go b/race_test.go index 6e4ab4419a..52181e064f 100644 --- a/race_test.go +++ b/race_test.go @@ -290,13 +290,6 @@ var _ = Describe("races", func() { Expect(atomic.LoadUint32(&received)).To(Equal(uint32(C * N))) }) - It("should WithContext", func() { - perform(C, func(_ int) { - err := client.WithContext(ctx).Ping(ctx).Err() - Expect(err).NotTo(HaveOccurred()) - }) - }) - It("should abort on context timeout", func() { opt := redisClusterOptions() client := cluster.newClusterClient(ctx, opt) diff --git a/redis.go b/redis.go index 7248057d2c..d292d938f7 100644 --- a/redis.go +++ b/redis.go @@ -574,19 +574,6 @@ func (c *Client) WithTimeout(timeout time.Duration) *Client { return clone } -func (c *Client) Context() context.Context { - return c.ctx -} - -func (c *Client) WithContext(ctx context.Context) *Client { - if ctx == nil { - panic("nil context") - } - clone := c.clone() - clone.ctx = ctx - return clone -} - func (c *Client) Conn(ctx context.Context) *Conn { return newConn(ctx, c.opt, pool.NewStickyConnPool(c.connPool)) } @@ -629,7 +616,6 @@ func (c *Client) Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmd func (c *Client) Pipeline() Pipeliner { pipe := Pipeline{ - ctx: c.ctx, exec: c.processPipeline, } pipe.init() @@ -643,7 +629,6 @@ func (c *Client) TxPipelined(ctx context.Context, fn func(Pipeliner) error) ([]C // TxPipeline acts like Pipeline, but wraps queued commands with MULTI/EXEC. func (c *Client) TxPipeline() Pipeliner { pipe := Pipeline{ - ctx: c.ctx, exec: c.processTxPipeline, } pipe.init() @@ -757,7 +742,6 @@ func (c *Conn) Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder func (c *Conn) Pipeline() Pipeliner { pipe := Pipeline{ - ctx: c.ctx, exec: c.processPipeline, } pipe.init() @@ -771,7 +755,6 @@ func (c *Conn) TxPipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmd // TxPipeline acts like Pipeline, but wraps queued commands with MULTI/EXEC. func (c *Conn) TxPipeline() Pipeliner { pipe := Pipeline{ - ctx: c.ctx, exec: c.processTxPipeline, } pipe.init() diff --git a/ring.go b/ring.go index 21a9264946..9e24ec52fd 100644 --- a/ring.go +++ b/ring.go @@ -432,21 +432,6 @@ func NewRing(opt *RingOptions) *Ring { return &ring } -func (c *Ring) Context() context.Context { - return c.ctx -} - -func (c *Ring) WithContext(ctx context.Context) *Ring { - if ctx == nil { - panic("nil context") - } - clone := *c - clone.cmdable = clone.Process - clone.hooks.lock() - clone.ctx = ctx - return &clone -} - // Do creates a Cmd from the args and processes the cmd. func (c *Ring) Do(ctx context.Context, args ...interface{}) *Cmd { cmd := NewCmd(ctx, args...) @@ -619,7 +604,6 @@ func (c *Ring) Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder func (c *Ring) Pipeline() Pipeliner { pipe := Pipeline{ - ctx: c.ctx, exec: c.processPipeline, } pipe.init() @@ -638,7 +622,6 @@ func (c *Ring) TxPipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmd func (c *Ring) TxPipeline() Pipeliner { pipe := Pipeline{ - ctx: c.ctx, exec: c.processTxPipeline, } pipe.init() diff --git a/sentinel.go b/sentinel.go index 5cec0c5398..6649a27be5 100644 --- a/sentinel.go +++ b/sentinel.go @@ -256,7 +256,6 @@ func masterReplicaDialer( type SentinelClient struct { *baseClient hooks - ctx context.Context } func NewSentinelClient(opt *Options) *SentinelClient { @@ -266,24 +265,10 @@ func NewSentinelClient(opt *Options) *SentinelClient { opt: opt, connPool: newConnPool(opt), }, - ctx: context.Background(), } return c } -func (c *SentinelClient) Context() context.Context { - return c.ctx -} - -func (c *SentinelClient) WithContext(ctx context.Context) *SentinelClient { - if ctx == nil { - panic("nil context") - } - clone := *c - clone.ctx = ctx - return &clone -} - func (c *SentinelClient) Process(ctx context.Context, cmd Cmder) error { return c.hooks.process(ctx, cmd, c.baseClient.process) } diff --git a/tx.go b/tx.go index 079149fb1e..9381ed87ad 100644 --- a/tx.go +++ b/tx.go @@ -41,21 +41,6 @@ func (c *Tx) init() { c.statefulCmdable = c.Process } -func (c *Tx) Context() context.Context { - return c.ctx -} - -func (c *Tx) WithContext(ctx context.Context) *Tx { - if ctx == nil { - panic("nil context") - } - clone := *c - clone.init() - clone.hooks.lock() - clone.ctx = ctx - return &clone -} - func (c *Tx) Process(ctx context.Context, cmd Cmder) error { return c.hooks.process(ctx, cmd, c.baseClient.process) } @@ -109,7 +94,6 @@ func (c *Tx) Unwatch(ctx context.Context, keys ...string) *StatusCmd { // Pipeline creates a pipeline. Usually it is more convenient to use Pipelined. func (c *Tx) Pipeline() Pipeliner { pipe := Pipeline{ - ctx: c.ctx, exec: func(ctx context.Context, cmds []Cmder) error { return c.hooks.processPipeline(ctx, cmds, c.baseClient.processPipeline) }, @@ -139,7 +123,6 @@ func (c *Tx) TxPipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder // TxPipeline creates a pipeline. Usually it is more convenient to use TxPipelined. func (c *Tx) TxPipeline() Pipeliner { pipe := Pipeline{ - ctx: c.ctx, exec: func(ctx context.Context, cmds []Cmder) error { return c.hooks.processTxPipeline(ctx, cmds, c.baseClient.processTxPipeline) }, diff --git a/universal.go b/universal.go index c89b3e5d74..257a205596 100644 --- a/universal.go +++ b/universal.go @@ -182,7 +182,6 @@ func (o *UniversalOptions) Simple() *Options { // clients in different environments. type UniversalClient interface { Cmdable - Context() context.Context AddHook(Hook) Watch(ctx context.Context, fn func(*Tx) error, keys ...string) error Do(ctx context.Context, args ...interface{}) *Cmd From b6d2a925297e3e516eb5c76c114c1c9fcd5b68c5 Mon Sep 17 00:00:00 2001 From: Back Yu Date: Fri, 10 Jun 2022 21:19:02 +0800 Subject: [PATCH 045/621] fix: #2114 for redis-server not support Hello Using `strings.HasPrefix` instead of `equal` --- redis.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/redis.go b/redis.go index d292d938f7..ecc79848fc 100644 --- a/redis.go +++ b/redis.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strings" "sync/atomic" "time" @@ -228,11 +229,11 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { var auth bool - // For redis-server <6.0 that does not support the Hello command, + // For redis-server < 6.0 that does not support the Hello command, // we continue to provide services with RESP2. if err := conn.Hello(ctx, 3, username, password, "").Err(); err == nil { auth = true - } else if err.Error() != "ERR unknown command 'hello'" { + } else if !strings.HasPrefix(err.Error(), "ERR unknown command") { return err } From 6e561bc5b9a492093e4a90107d2558c70959d324 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jun 2022 01:28:00 +0000 Subject: [PATCH 046/621] chore(deps): bump wagoid/commitlint-github-action from 4 to 5 Bumps [wagoid/commitlint-github-action](https://github.com/wagoid/commitlint-github-action) from 4 to 5. - [Release notes](https://github.com/wagoid/commitlint-github-action/releases) - [Changelog](https://github.com/wagoid/commitlint-github-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/wagoid/commitlint-github-action/compare/v4...v5) --- updated-dependencies: - dependency-name: wagoid/commitlint-github-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/commitlint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 5fcfeaea7b..af8a615ec6 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -8,4 +8,4 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: wagoid/commitlint-github-action@v4 + - uses: wagoid/commitlint-github-action@v5 From 89d6dfe09a88321d445858c1c5b24d2757b95a3e Mon Sep 17 00:00:00 2001 From: youseebiggirl <49178981+youseebiggirl@users.noreply.github.com> Date: Sat, 25 Jun 2022 20:11:46 +0800 Subject: [PATCH 047/621] fix: ignore Nil error when reading EntriesRead --- command.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command.go b/command.go index ee1e8d17a9..a6f74dbe84 100644 --- a/command.go +++ b/command.go @@ -2047,7 +2047,7 @@ func (cmd *XInfoGroupsCmd) readReply(rd *proto.Reader) error { } case "entries-read": group.EntriesRead, err = rd.ReadInt() - if err != nil { + if err != nil && err != Nil { return err } case "lag": From 64f972fbeae401e52a2c066a0e1c922af617e15c Mon Sep 17 00:00:00 2001 From: Ben Keith Date: Fri, 1 Jul 2022 10:14:52 -0400 Subject: [PATCH 048/621] fix: disregard failed pings in updateLatency() for cluster nodes It is possible that a ping command might fail very quickly due to an immediate connection refused message or some other server failure condition. In this case, the derived latency is not reliable and should not be used to compare this node to other nodes in the cluster. This change will only count successful Ping commands in the average latency and in the case of no successful Pings, set the latency to an arbitrarily high value to make this node have the least priority when routing by latency. --- cluster.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/cluster.go b/cluster.go index e3a344fcb3..bd8fdd7371 100644 --- a/cluster.go +++ b/cluster.go @@ -204,15 +204,26 @@ func (n *clusterNode) updateLatency() { const numProbe = 10 var dur uint64 + successes := 0 for i := 0; i < numProbe; i++ { time.Sleep(time.Duration(10+rand.Intn(10)) * time.Millisecond) start := time.Now() - n.Client.Ping(context.TODO()) - dur += uint64(time.Since(start) / time.Microsecond) + err := n.Client.Ping(context.TODO()).Err() + if err == nil { + dur += uint64(time.Since(start) / time.Microsecond) + successes++ + } } - latency := float64(dur) / float64(numProbe) + var latency float64 + if successes == 0 { + // If none of the pings worked, set latency to some arbitrarily high value so this node gets + // least priority. + latency = float64((1 * time.Minute) / time.Microsecond) + } else { + latency = float64(dur) / float64(successes) + } atomic.StoreUint32(&n.latency, uint32(latency+0.5)) } From fa4d1ea8398cd729ad5cbaaff88e4b8805393945 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Wed, 6 Jul 2022 14:28:42 -0700 Subject: [PATCH 049/621] fix: log errors from cmdsInfoCache Since the error gets swallowed in cmdInfo(), it's important to log it so it's possible for the user to see what the error was. --- cluster.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cluster.go b/cluster.go index bd8fdd7371..c6d8cc5874 100644 --- a/cluster.go +++ b/cluster.go @@ -1605,6 +1605,7 @@ func (c *ClusterClient) cmdsInfo(ctx context.Context) (map[string]*CommandInfo, func (c *ClusterClient) cmdInfo(name string) *CommandInfo { cmdsInfo, err := c.cmdsInfoCache.Get(c.ctx) if err != nil { + internal.Logger.Printf(context.TODO(), "getting command info: %s", err) return nil } From 03376a5d9c7dfd7197b14ce13b24a0431a07a663 Mon Sep 17 00:00:00 2001 From: Ben Keith Date: Thu, 7 Jul 2022 14:42:57 -0400 Subject: [PATCH 050/621] fix: additional node failures in clustered pipelined reads This causes a node to be marked as failing if the client is in READONLY mode and any error occurs that is either a LOADING error (existing behvaior) or any non-redis error (e.g. connection error, timeout, etc.). This prevents that node from being tried again on the next attempt as usually non-redis errors are a strong indication that that node is not operational or degraded in some way. --- cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cluster.go b/cluster.go index c6d8cc5874..da55d7ec37 100644 --- a/cluster.go +++ b/cluster.go @@ -1212,7 +1212,7 @@ func (c *ClusterClient) pipelineReadCmds( continue } - if c.opt.ReadOnly && isLoadingError(err) { + if c.opt.ReadOnly && (isLoadingError(err) || !isRedisError(err)) { node.MarkAsFailing() return err } From 092a6923840ef3d94d49c97498cf25edd906f71f Mon Sep 17 00:00:00 2001 From: Knut Zuidema Date: Wed, 13 Jul 2022 07:49:28 +0200 Subject: [PATCH 051/621] refactor: remove unused context attribute from conn (#2150) --- example_test.go | 2 +- redis.go | 10 ++++------ redis_test.go | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/example_test.go b/example_test.go index 3e05f21b45..56cf9018f3 100644 --- a/example_test.go +++ b/example_test.go @@ -155,7 +155,7 @@ func ExampleClient() { } func ExampleConn() { - conn := rdb.Conn(context.Background()) + conn := rdb.Conn() err := conn.ClientSetName(ctx, "foobar").Err() if err != nil { diff --git a/redis.go b/redis.go index ecc79848fc..9a2f6a1f96 100644 --- a/redis.go +++ b/redis.go @@ -225,7 +225,7 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { } connPool := pool.NewSingleConnPool(c.connPool, cn) - conn := newConn(ctx, c.opt, connPool) + conn := newConn(c.opt, connPool) var auth bool @@ -575,8 +575,8 @@ func (c *Client) WithTimeout(timeout time.Duration) *Client { return clone } -func (c *Client) Conn(ctx context.Context) *Conn { - return newConn(ctx, c.opt, pool.NewStickyConnPool(c.connPool)) +func (c *Client) Conn() *Conn { + return newConn(c.opt, pool.NewStickyConnPool(c.connPool)) } // Do creates a Cmd from the args and processes the cmd. @@ -707,10 +707,9 @@ type conn struct { // for a continuous single Redis connection. type Conn struct { *conn - ctx context.Context } -func newConn(ctx context.Context, opt *Options, connPool pool.Pooler) *Conn { +func newConn(opt *Options, connPool pool.Pooler) *Conn { c := Conn{ conn: &conn{ baseClient: baseClient{ @@ -718,7 +717,6 @@ func newConn(ctx context.Context, opt *Options, connPool pool.Pooler) *Conn { connPool: connPool, }, }, - ctx: ctx, } c.cmdable = c.Process c.statefulCmdable = c.Process diff --git a/redis_test.go b/redis_test.go index af721fe74c..a7029b8701 100644 --- a/redis_test.go +++ b/redis_test.go @@ -296,7 +296,7 @@ var _ = Describe("Client", func() { }) It("should Conn", func() { - err := client.Conn(ctx).Get(ctx, "this-key-does-not-exist").Err() + err := client.Conn().Get(ctx, "this-key-does-not-exist").Err() Expect(err).To(Equal(redis.Nil)) }) From a80b84f01f9fc0d3e6f08445ba21f7e07880775e Mon Sep 17 00:00:00 2001 From: Max Riveiro Date: Wed, 13 Jul 2022 18:09:42 +0300 Subject: [PATCH 052/621] fix: handle panic in ringShards Hash function when Ring got closed Fixes #2126 --- ring.go | 26 ++++++++++++-------------- ring_test.go | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/ring.go b/ring.go index 9e24ec52fd..d42bfabff8 100644 --- a/ring.go +++ b/ring.go @@ -259,10 +259,11 @@ func (c *ringShards) Hash(key string) string { var hash string c.mu.RLock() + defer c.mu.RUnlock() + if c.numShard > 0 { hash = c.hash.Get(key) } - c.mu.RUnlock() return hash } @@ -271,27 +272,22 @@ func (c *ringShards) GetByKey(key string) (*ringShard, error) { key = hashtag.Key(key) c.mu.RLock() + defer c.mu.RUnlock() if c.closed { - c.mu.RUnlock() return nil, pool.ErrClosed } if c.numShard == 0 { - c.mu.RUnlock() return nil, errRingShardsDown } hash := c.hash.Get(key) if hash == "" { - c.mu.RUnlock() return nil, errRingShardsDown } - shard := c.shards[hash] - c.mu.RUnlock() - - return shard, nil + return c.shards[hash], nil } func (c *ringShards) GetByName(shardName string) (*ringShard, error) { @@ -300,9 +296,9 @@ func (c *ringShards) GetByName(shardName string) (*ringShard, error) { } c.mu.RLock() - shard := c.shards[shardName] - c.mu.RUnlock() - return shard, nil + defer c.mu.RUnlock() + + return c.shards[shardName], nil } func (c *ringShards) Random() (*ringShard, error) { @@ -357,9 +353,9 @@ func (c *ringShards) rebalance() { func (c *ringShards) Len() int { c.mu.RLock() - l := c.numShard - c.mu.RUnlock() - return l + defer c.mu.RUnlock() + + return c.numShard } func (c *ringShards) Close() error { @@ -377,8 +373,10 @@ func (c *ringShards) Close() error { firstErr = err } } + c.hash = nil c.shards = nil + c.numShard = 0 c.list = nil return firstErr diff --git a/ring_test.go b/ring_test.go index 50b13ffde2..1a6ec84b99 100644 --- a/ring_test.go +++ b/ring_test.go @@ -114,6 +114,21 @@ var _ = Describe("Redis Ring", func() { }) Describe("pipeline", func() { + It("doesn't panic closed ring, returns error", func() { + pipe := ring.Pipeline() + for i := 0; i < 3; i++ { + err := pipe.Set(ctx, fmt.Sprintf("key%d", i), "value", 0).Err() + Expect(err).NotTo(HaveOccurred()) + } + + Expect(ring.Close()).NotTo(HaveOccurred()) + + Expect(func() { + _, execErr := pipe.Exec(ctx) + Expect(execErr).To(HaveOccurred()) + }).NotTo(Panic()) + }) + It("distributes keys", func() { pipe := ring.Pipeline() for i := 0; i < 100; i++ { From e061db8c13fd6b5e007d73370873026e360719de Mon Sep 17 00:00:00 2001 From: Knut Zuidema Date: Thu, 14 Jul 2022 12:43:42 +0200 Subject: [PATCH 053/621] refactor: remove unused context attributes (#2154) * refactor: remove unused context field --- cluster.go | 30 ++++++++++++++---------------- redis.go | 2 -- ring.go | 2 -- sentinel.go | 1 - tx.go | 6 ++---- 5 files changed, 16 insertions(+), 25 deletions(-) diff --git a/cluster.go b/cluster.go index c6d8cc5874..6c492cc6b1 100644 --- a/cluster.go +++ b/cluster.go @@ -708,7 +708,6 @@ type ClusterClient struct { *clusterClient cmdable hooks - ctx context.Context } // NewClusterClient returns a Redis Cluster client as described in @@ -721,7 +720,6 @@ func NewClusterClient(opt *ClusterOptions) *ClusterClient { opt: opt, nodes: newClusterNodes(opt), }, - ctx: context.Background(), } c.state = newClusterStateHolder(c.loadState) c.cmdsInfoCache = newCmdsInfoCache(c.cmdsInfo) @@ -765,8 +763,8 @@ func (c *ClusterClient) Process(ctx context.Context, cmd Cmder) error { } func (c *ClusterClient) process(ctx context.Context, cmd Cmder) error { - cmdInfo := c.cmdInfo(cmd.Name()) - slot := c.cmdSlot(cmd) + cmdInfo := c.cmdInfo(ctx, cmd.Name()) + slot := c.cmdSlot(ctx, cmd) var node *clusterNode var ask bool @@ -1141,9 +1139,9 @@ func (c *ClusterClient) mapCmdsByNode(ctx context.Context, cmdsMap *cmdsMap, cmd return err } - if c.opt.ReadOnly && c.cmdsAreReadOnly(cmds) { + if c.opt.ReadOnly && c.cmdsAreReadOnly(ctx, cmds) { for _, cmd := range cmds { - slot := c.cmdSlot(cmd) + slot := c.cmdSlot(ctx, cmd) node, err := c.slotReadOnlyNode(state, slot) if err != nil { return err @@ -1154,7 +1152,7 @@ func (c *ClusterClient) mapCmdsByNode(ctx context.Context, cmdsMap *cmdsMap, cmd } for _, cmd := range cmds { - slot := c.cmdSlot(cmd) + slot := c.cmdSlot(ctx, cmd) node, err := state.slotMasterNode(slot) if err != nil { return err @@ -1164,9 +1162,9 @@ func (c *ClusterClient) mapCmdsByNode(ctx context.Context, cmdsMap *cmdsMap, cmd return nil } -func (c *ClusterClient) cmdsAreReadOnly(cmds []Cmder) bool { +func (c *ClusterClient) cmdsAreReadOnly(ctx context.Context, cmds []Cmder) bool { for _, cmd := range cmds { - cmdInfo := c.cmdInfo(cmd.Name()) + cmdInfo := c.cmdInfo(ctx, cmd.Name()) if cmdInfo == nil || !cmdInfo.ReadOnly { return false } @@ -1278,7 +1276,7 @@ func (c *ClusterClient) _processTxPipeline(ctx context.Context, cmds []Cmder) er return err } - cmdsMap := c.mapCmdsBySlot(cmds) + cmdsMap := c.mapCmdsBySlot(ctx, cmds) for slot, cmds := range cmdsMap { node, err := state.slotMasterNode(slot) if err != nil { @@ -1329,10 +1327,10 @@ func (c *ClusterClient) _processTxPipeline(ctx context.Context, cmds []Cmder) er return cmdsFirstErr(cmds) } -func (c *ClusterClient) mapCmdsBySlot(cmds []Cmder) map[int][]Cmder { +func (c *ClusterClient) mapCmdsBySlot(ctx context.Context, cmds []Cmder) map[int][]Cmder { cmdsMap := make(map[int][]Cmder) for _, cmd := range cmds { - slot := c.cmdSlot(cmd) + slot := c.cmdSlot(ctx, cmd) cmdsMap[slot] = append(cmdsMap[slot], cmd) } return cmdsMap @@ -1602,8 +1600,8 @@ func (c *ClusterClient) cmdsInfo(ctx context.Context) (map[string]*CommandInfo, return nil, firstErr } -func (c *ClusterClient) cmdInfo(name string) *CommandInfo { - cmdsInfo, err := c.cmdsInfoCache.Get(c.ctx) +func (c *ClusterClient) cmdInfo(ctx context.Context, name string) *CommandInfo { + cmdsInfo, err := c.cmdsInfoCache.Get(ctx) if err != nil { internal.Logger.Printf(context.TODO(), "getting command info: %s", err) return nil @@ -1616,13 +1614,13 @@ func (c *ClusterClient) cmdInfo(name string) *CommandInfo { return info } -func (c *ClusterClient) cmdSlot(cmd Cmder) int { +func (c *ClusterClient) cmdSlot(ctx context.Context, cmd Cmder) int { args := cmd.Args() if args[0] == "cluster" && args[1] == "getkeysinslot" { return args[2].(int) } - cmdInfo := c.cmdInfo(cmd.Name()) + cmdInfo := c.cmdInfo(ctx, cmd.Name()) return cmdSlot(cmd, cmdFirstKeyPos(cmd, cmdInfo)) } diff --git a/redis.go b/redis.go index 9a2f6a1f96..f558181240 100644 --- a/redis.go +++ b/redis.go @@ -546,7 +546,6 @@ type Client struct { *baseClient cmdable hooks - ctx context.Context } // NewClient returns a client to the Redis Server specified by Options. @@ -555,7 +554,6 @@ func NewClient(opt *Options) *Client { c := Client{ baseClient: newBaseClient(opt, newConnPool(opt)), - ctx: context.Background(), } c.cmdable = c.Process diff --git a/ring.go b/ring.go index 9e24ec52fd..7126da676d 100644 --- a/ring.go +++ b/ring.go @@ -410,7 +410,6 @@ type Ring struct { *ring cmdable hooks - ctx context.Context } func NewRing(opt *RingOptions) *Ring { @@ -421,7 +420,6 @@ func NewRing(opt *RingOptions) *Ring { opt: opt, shards: newRingShards(opt), }, - ctx: context.Background(), } ring.cmdsInfoCache = newCmdsInfoCache(ring.cmdsInfo) diff --git a/sentinel.go b/sentinel.go index 6649a27be5..f318e0fe38 100644 --- a/sentinel.go +++ b/sentinel.go @@ -209,7 +209,6 @@ func NewFailoverClient(failoverOpt *FailoverOptions) *Client { c := Client{ baseClient: newBaseClient(opt, connPool), - ctx: context.Background(), } c.cmdable = c.Process c.onClose = failover.Close diff --git a/tx.go b/tx.go index 9381ed87ad..61375e080f 100644 --- a/tx.go +++ b/tx.go @@ -20,17 +20,15 @@ type Tx struct { cmdable statefulCmdable hooks - ctx context.Context } -func (c *Client) newTx(ctx context.Context) *Tx { +func (c *Client) newTx() *Tx { tx := Tx{ baseClient: baseClient{ opt: c.opt, connPool: pool.NewStickyConnPool(c.connPool), }, hooks: c.hooks.clone(), - ctx: ctx, } tx.init() return &tx @@ -50,7 +48,7 @@ func (c *Tx) Process(ctx context.Context, cmd Cmder) error { // // The transaction is automatically closed when fn exits. func (c *Client) Watch(ctx context.Context, fn func(*Tx) error, keys ...string) error { - tx := c.newTx(ctx) + tx := c.newTx() defer tx.Close(ctx) if len(keys) > 0 { if err := tx.Watch(ctx, keys...).Err(); err != nil { From f032c126db3e2c1a239ce1790b0ab81994df75cf Mon Sep 17 00:00:00 2001 From: Max Riveiro Date: Thu, 14 Jul 2022 22:32:31 +0300 Subject: [PATCH 054/621] fix: provide a signal channel to end heartbeat goroutine --- ring.go | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/ring.go b/ring.go index 7126da676d..5ea4ae5e02 100644 --- a/ring.go +++ b/ring.go @@ -310,25 +310,30 @@ func (c *ringShards) Random() (*ringShard, error) { } // Heartbeat monitors state of each shard in the ring. -func (c *ringShards) Heartbeat(frequency time.Duration) { +func (c *ringShards) Heartbeat(frequency time.Duration, closeCh chan struct{}) { ticker := time.NewTicker(frequency) defer ticker.Stop() ctx := context.Background() - for range ticker.C { - var rebalance bool - - for _, shard := range c.List() { - err := shard.Client.Ping(ctx).Err() - isUp := err == nil || err == pool.ErrPoolTimeout - if shard.Vote(isUp) { - internal.Logger.Printf(context.Background(), "ring shard state changed: %s", shard) - rebalance = true + for { + select { + case <-ticker.C: + var rebalance bool + + for _, shard := range c.List() { + err := shard.Client.Ping(ctx).Err() + isUp := err == nil || err == pool.ErrPoolTimeout + if shard.Vote(isUp) { + internal.Logger.Printf(ctx, "ring shard state changed: %s", shard) + rebalance = true + } } - } - if rebalance { - c.rebalance() + if rebalance { + c.rebalance() + } + case <-closeCh: + return } } } @@ -387,9 +392,10 @@ func (c *ringShards) Close() error { //------------------------------------------------------------------------------ type ring struct { - opt *RingOptions - shards *ringShards - cmdsInfoCache *cmdsInfoCache //nolint:structcheck + opt *RingOptions + shards *ringShards + cmdsInfoCache *cmdsInfoCache //nolint:structcheck + hearbeatCloseSignal chan struct{} } // Ring is a Redis client that uses consistent hashing to distribute @@ -415,17 +421,20 @@ type Ring struct { func NewRing(opt *RingOptions) *Ring { opt.init() + hearbeatCloseSignal := make(chan struct{}) + ring := Ring{ ring: &ring{ - opt: opt, - shards: newRingShards(opt), + opt: opt, + shards: newRingShards(opt), + hearbeatCloseSignal: hearbeatCloseSignal, }, } ring.cmdsInfoCache = newCmdsInfoCache(ring.cmdsInfo) ring.cmdable = ring.Process - go ring.shards.Heartbeat(opt.HeartbeatFrequency) + go ring.shards.Heartbeat(opt.HeartbeatFrequency, hearbeatCloseSignal) return &ring } @@ -713,5 +722,6 @@ func (c *Ring) Watch(ctx context.Context, fn func(*Tx) error, keys ...string) er // It is rare to Close a Ring, as the Ring is meant to be long-lived // and shared between many goroutines. func (c *Ring) Close() error { + close(c.hearbeatCloseSignal) return c.shards.Close() } From 20d0ca235efff48ad48cc05b98790b825d4ba979 Mon Sep 17 00:00:00 2001 From: Max Riveiro Date: Tue, 19 Jul 2022 22:50:12 +0300 Subject: [PATCH 055/621] fix: replace heartbeat signal channel with context.WithCancel --- ring.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ring.go b/ring.go index 5ea4ae5e02..444acaec3d 100644 --- a/ring.go +++ b/ring.go @@ -310,11 +310,10 @@ func (c *ringShards) Random() (*ringShard, error) { } // Heartbeat monitors state of each shard in the ring. -func (c *ringShards) Heartbeat(frequency time.Duration, closeCh chan struct{}) { +func (c *ringShards) Heartbeat(ctx context.Context, frequency time.Duration) { ticker := time.NewTicker(frequency) defer ticker.Stop() - ctx := context.Background() for { select { case <-ticker.C: @@ -332,7 +331,7 @@ func (c *ringShards) Heartbeat(frequency time.Duration, closeCh chan struct{}) { if rebalance { c.rebalance() } - case <-closeCh: + case <-ctx.Done(): return } } @@ -392,10 +391,10 @@ func (c *ringShards) Close() error { //------------------------------------------------------------------------------ type ring struct { - opt *RingOptions - shards *ringShards - cmdsInfoCache *cmdsInfoCache //nolint:structcheck - hearbeatCloseSignal chan struct{} + opt *RingOptions + shards *ringShards + cmdsInfoCache *cmdsInfoCache //nolint:structcheck + heartbeatCancelFn context.CancelFunc } // Ring is a Redis client that uses consistent hashing to distribute @@ -421,20 +420,20 @@ type Ring struct { func NewRing(opt *RingOptions) *Ring { opt.init() - hearbeatCloseSignal := make(chan struct{}) + hbCtx, hbCancel := context.WithCancel(context.Background()) ring := Ring{ ring: &ring{ - opt: opt, - shards: newRingShards(opt), - hearbeatCloseSignal: hearbeatCloseSignal, + opt: opt, + shards: newRingShards(opt), + heartbeatCancelFn: hbCancel, }, } ring.cmdsInfoCache = newCmdsInfoCache(ring.cmdsInfo) ring.cmdable = ring.Process - go ring.shards.Heartbeat(opt.HeartbeatFrequency, hearbeatCloseSignal) + go ring.shards.Heartbeat(hbCtx, opt.HeartbeatFrequency) return &ring } @@ -722,6 +721,7 @@ func (c *Ring) Watch(ctx context.Context, fn func(*Tx) error, keys ...string) er // It is rare to Close a Ring, as the Ring is meant to be long-lived // and shared between many goroutines. func (c *Ring) Close() error { - close(c.hearbeatCloseSignal) + c.heartbeatCancelFn() + return c.shards.Close() } From 9e16c79951e7769621b7320f1ecdf04baf539b82 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Mon, 4 Jul 2022 11:23:44 +1000 Subject: [PATCH 056/621] fix: don't panic when test cannot start --- cluster_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cluster_test.go b/cluster_test.go index 42f95fbd9d..ee37dc2dba 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -82,8 +82,10 @@ func (s *clusterScenario) newClusterClient( func (s *clusterScenario) Close() error { for _, port := range s.ports { - processes[port].Close() - delete(processes, port) + if process, ok := processes[port]; ok { + process.Close() + delete(processes, port) + } } return nil } From 43d0cbb9b815e471740d8f78c4aad9953e3da9fd Mon Sep 17 00:00:00 2001 From: Knut Zuidema Date: Thu, 21 Jul 2022 16:02:50 +0200 Subject: [PATCH 057/621] feat(extra/redisprometheus): prometheus.Collector implementation for redis clients Signed-off-by: Knut Zuidema --- extra/redisprometheus/README.md | 26 ++ extra/redisprometheus/collector.go | 117 +++++++ extra/redisprometheus/go.mod | 23 ++ extra/redisprometheus/go.sum | 511 +++++++++++++++++++++++++++++ 4 files changed, 677 insertions(+) create mode 100644 extra/redisprometheus/README.md create mode 100644 extra/redisprometheus/collector.go create mode 100644 extra/redisprometheus/go.mod create mode 100644 extra/redisprometheus/go.sum diff --git a/extra/redisprometheus/README.md b/extra/redisprometheus/README.md new file mode 100644 index 0000000000..da4c92e73d --- /dev/null +++ b/extra/redisprometheus/README.md @@ -0,0 +1,26 @@ +# Prometheus Metric Collector + +This package implements a [`prometheus.Collector`](https://pkg.go.dev/github.com/prometheus/client_golang@v1.12.2/prometheus#Collector) +for collecting metrics about the connection pool used by the various redis clients. +Supported clients are `redis.Client`, `redis.ClusterClient`, `redis.Ring` and `redis.UniversalClient`. + +### Example + +```go +client := redis.NewClient(options) +collector := redisprometheus.NewCollector(namespace, subsystem, client) +prometheus.MustRegister(collector) +``` + +### Metrics + +| Name | Type | Description | +|---------------------------|----------------|-----------------------------------------------------------------------------| +| `pool_hit_total` | Counter metric | number of times a connection was found in the pool | +| `pool_miss_total` | Counter metric | number of times a connection was not found in the pool | +| `pool_timeout_total` | Counter metric | number of times a timeout occurred when getting a connection from the pool | +| `pool_conn_total_current` | Gauge metric | current number of connections in the pool | +| `pool_conn_idle_current` | Gauge metric | current number of idle connections in the pool | +| `pool_conn_stale_total` | Counter metric | number of times a connection was removed from the pool because it was stale | + + diff --git a/extra/redisprometheus/collector.go b/extra/redisprometheus/collector.go new file mode 100644 index 0000000000..45d490a741 --- /dev/null +++ b/extra/redisprometheus/collector.go @@ -0,0 +1,117 @@ +package redisprometheus + +import ( + "github.com/prometheus/client_golang/prometheus" + + "github.com/go-redis/redis/v9" +) + +// StatGetter provides a method to get pool statistics. +type StatGetter interface { + PoolStats() *redis.PoolStats +} + +// Collector collects statistics from a redis client. +// It implements the prometheus.Collector interface. +type Collector struct { + getter StatGetter + hitDesc *prometheus.Desc + missDesc *prometheus.Desc + timeoutDesc *prometheus.Desc + totalDesc *prometheus.Desc + idleDesc *prometheus.Desc + staleDesc *prometheus.Desc +} + +var _ prometheus.Collector = (*Collector)(nil) + +// NewCollector returns a new Collector based on the provided StatGetter. +// The given namespace and subsystem are used to build the fully qualified metric name, +// i.e. "{namespace}_{subsystem}_{metric}". +// The provided metrics are: +// * pool_hit_total +// * pool_miss_total +// * pool_timeout_total +// * pool_conn_total_current +// * pool_conn_idle_current +// * pool_conn_stale_total +func NewCollector(namespace, subsystem string, getter StatGetter) *Collector { + return &Collector{ + getter: getter, + hitDesc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "pool_hit_total"), + "Number of times a connection was found in the pool", + nil, nil, + ), + missDesc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "pool_miss_total"), + "Number of times a connection was not found in the pool", + nil, nil, + ), + timeoutDesc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "pool_timeout_total"), + "Number of times a timeout occurred when looking for a connection in the pool", + nil, nil, + ), + totalDesc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "pool_conn_total_current"), + "Current number of connections in the pool", + nil, nil, + ), + idleDesc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "pool_conn_idle_current"), + "Current number of idle connections in the pool", + nil, nil, + ), + staleDesc: prometheus.NewDesc( + prometheus.BuildFQName(namespace, subsystem, "pool_conn_stale_total"), + "Number of times a connection was removed from the pool because it was stale", + nil, nil, + ), + } +} + +// Describe implements the prometheus.Collector interface. +func (s *Collector) Describe(descs chan<- *prometheus.Desc) { + descs <- s.hitDesc + descs <- s.missDesc + descs <- s.timeoutDesc + descs <- s.totalDesc + descs <- s.idleDesc + descs <- s.staleDesc +} + +// Collect implements the prometheus.Collector interface. +func (s *Collector) Collect(metrics chan<- prometheus.Metric) { + stats := s.getter.PoolStats() + metrics <- prometheus.MustNewConstMetric( + s.hitDesc, + prometheus.CounterValue, + float64(stats.Hits), + ) + metrics <- prometheus.MustNewConstMetric( + s.missDesc, + prometheus.CounterValue, + float64(stats.Misses), + ) + metrics <- prometheus.MustNewConstMetric( + s.timeoutDesc, + prometheus.CounterValue, + float64(stats.Timeouts), + ) + metrics <- prometheus.MustNewConstMetric( + s.totalDesc, + prometheus.GaugeValue, + float64(stats.TotalConns), + ) + metrics <- prometheus.MustNewConstMetric( + s.idleDesc, + prometheus.GaugeValue, + float64(stats.IdleConns), + ) + metrics <- prometheus.MustNewConstMetric( + s.staleDesc, + prometheus.CounterValue, + float64(stats.StaleConns), + ) +} diff --git a/extra/redisprometheus/go.mod b/extra/redisprometheus/go.mod new file mode 100644 index 0000000000..b9e7a9fa32 --- /dev/null +++ b/extra/redisprometheus/go.mod @@ -0,0 +1,23 @@ +module github.com/go-redis/redis/extra/redisprometheus/v9 + +go 1.17 + +replace github.com/go-redis/redis/v9 => ../.. + +require ( + github.com/go-redis/redis/v9 v9.0.0-beta.1 + github.com/prometheus/client_golang v1.12.2 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + google.golang.org/protobuf v1.26.0 // indirect +) diff --git a/extra/redisprometheus/go.sum b/extra/redisprometheus/go.sum new file mode 100644 index 0000000000..03a550f48f --- /dev/null +++ b/extra/redisprometheus/go.sum @@ -0,0 +1,511 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From 2be58234e3828eb0b51223a58a6212a68d2bf78e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 01:30:21 +0000 Subject: [PATCH 058/621] chore(deps): bump github.com/onsi/gomega from 1.19.0 to 1.20.0 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.19.0 to 1.20.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.19.0...v1.20.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 9 +++++---- go.sum | 29 +++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 6d5aed3f46..927841e0d3 100644 --- a/go.mod +++ b/go.mod @@ -6,15 +6,16 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.19.0 + github.com/onsi/gomega v1.20.0 ) require ( github.com/fsnotify/fsnotify v1.4.9 // indirect + github.com/google/go-cmp v0.5.8 // indirect github.com/nxadm/tail v1.4.8 // indirect - golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect - golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect + golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect + golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect golang.org/x/text v0.3.7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index dfa31aac45..224bfa9034 100644 --- a/go.sum +++ b/go.sum @@ -25,6 +25,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -36,32 +38,41 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -75,8 +86,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -87,6 +101,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -98,8 +113,9 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -108,5 +124,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From f6a8adc50cdaec30527f50d06468f9176ee674fe Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Thu, 28 Jul 2022 15:11:35 +0300 Subject: [PATCH 059/621] fix: remove conn reaper from the pool and uptrace option names --- CHANGELOG.md | 55 ++++++++---- cluster.go | 52 +++--------- internal/pool/bench_test.go | 18 ++-- internal/pool/conn_check.go | 6 +- internal/pool/pool.go | 162 ++++++++++++----------------------- internal/pool/pool_test.go | 165 ++++-------------------------------- main_test.go | 21 ++--- options.go | 62 ++++++++------ options_test.go | 26 +++--- pool_test.go | 35 +------- pubsub_test.go | 2 +- ring.go | 26 +++--- sentinel.go | 57 ++++++------- universal.go | 62 +++++++------- 14 files changed, 267 insertions(+), 482 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4377e94551..0350b02c0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,27 +1,44 @@ # [9.0.0-beta.1](https://github.com/go-redis/redis/compare/v8.11.5...v9.0.0-beta.1) (2022-06-04) - ### Bug Fixes -* **#1943:** xInfoConsumer.Idle should be time.Duration instead of int64 ([#2052](https://github.com/go-redis/redis/issues/2052)) ([997ab5e](https://github.com/go-redis/redis/commit/997ab5e7e3ddf53837917013a4babbded73e944f)), closes [#1943](https://github.com/go-redis/redis/issues/1943) -* add XInfoConsumers test ([6f1a1ac](https://github.com/go-redis/redis/commit/6f1a1ac284ea3f683eeb3b06a59969e8424b6376)) -* fix tests ([3a722be](https://github.com/go-redis/redis/commit/3a722be81180e4d2a9cf0a29dc9a1ee1421f5859)) -* remove test(XInfoConsumer.idle), not a stable return value when tested. ([f5fbb36](https://github.com/go-redis/redis/commit/f5fbb367e7d9dfd7f391fc535a7387002232fa8a)) -* update ChannelWithSubscriptions to accept options ([c98c5f0](https://github.com/go-redis/redis/commit/c98c5f0eebf8d254307183c2ce702a48256b718d)) -* update COMMAND parser for Redis 7 ([b0bb514](https://github.com/go-redis/redis/commit/b0bb514059249e01ed7328c9094e5b8a439dfb12)) -* use redis over ssh channel([#2057](https://github.com/go-redis/redis/issues/2057)) ([#2060](https://github.com/go-redis/redis/issues/2060)) ([3961b95](https://github.com/go-redis/redis/commit/3961b9577f622a3079fe74f8fc8da12ba67a77ff)) - +- **#1943:** xInfoConsumer.Idle should be time.Duration instead of int64 + ([#2052](https://github.com/go-redis/redis/issues/2052)) + ([997ab5e](https://github.com/go-redis/redis/commit/997ab5e7e3ddf53837917013a4babbded73e944f)), + closes [#1943](https://github.com/go-redis/redis/issues/1943) +- add XInfoConsumers test + ([6f1a1ac](https://github.com/go-redis/redis/commit/6f1a1ac284ea3f683eeb3b06a59969e8424b6376)) +- fix tests + ([3a722be](https://github.com/go-redis/redis/commit/3a722be81180e4d2a9cf0a29dc9a1ee1421f5859)) +- remove test(XInfoConsumer.idle), not a stable return value when tested. + ([f5fbb36](https://github.com/go-redis/redis/commit/f5fbb367e7d9dfd7f391fc535a7387002232fa8a)) +- update ChannelWithSubscriptions to accept options + ([c98c5f0](https://github.com/go-redis/redis/commit/c98c5f0eebf8d254307183c2ce702a48256b718d)) +- update COMMAND parser for Redis 7 + ([b0bb514](https://github.com/go-redis/redis/commit/b0bb514059249e01ed7328c9094e5b8a439dfb12)) +- use redis over ssh channel([#2057](https://github.com/go-redis/redis/issues/2057)) + ([#2060](https://github.com/go-redis/redis/issues/2060)) + ([3961b95](https://github.com/go-redis/redis/commit/3961b9577f622a3079fe74f8fc8da12ba67a77ff)) ### Features -* add ClientUnpause ([91171f5](https://github.com/go-redis/redis/commit/91171f5e19a261dc4cfbf8706626d461b6ba03e4)) -* add NewXPendingResult for unit testing XPending ([#2066](https://github.com/go-redis/redis/issues/2066)) ([b7fd09e](https://github.com/go-redis/redis/commit/b7fd09e59479bc6ed5b3b13c4645a3620fd448a3)) -* add WriteArg and Scan net.IP([#2062](https://github.com/go-redis/redis/issues/2062)) ([7d5167e](https://github.com/go-redis/redis/commit/7d5167e8624ac1515e146ed183becb97dadb3d1a)) -* **pool:** add check for badConnection ([a8a7665](https://github.com/go-redis/redis/commit/a8a7665ddf8cc657c5226b1826a8ee83dab4b8c1)), closes [#2053](https://github.com/go-redis/redis/issues/2053) -* provide a username and password callback method, so that the plaintext username and password will not be stored in the memory, and the username and password will only be generated once when the CredentialsProvider is called. After the method is executed, the username and password strings on the stack will be released. ([#2097](https://github.com/go-redis/redis/issues/2097)) ([56a3dbc](https://github.com/go-redis/redis/commit/56a3dbc7b656525eb88e0735e239d56e04a23bee)) -* upgrade to Redis 7 ([d09c27e](https://github.com/go-redis/redis/commit/d09c27e6046129fd27b1d275e5a13a477bd7f778)) - - +- add ClientUnpause + ([91171f5](https://github.com/go-redis/redis/commit/91171f5e19a261dc4cfbf8706626d461b6ba03e4)) +- add NewXPendingResult for unit testing XPending + ([#2066](https://github.com/go-redis/redis/issues/2066)) + ([b7fd09e](https://github.com/go-redis/redis/commit/b7fd09e59479bc6ed5b3b13c4645a3620fd448a3)) +- add WriteArg and Scan net.IP([#2062](https://github.com/go-redis/redis/issues/2062)) + ([7d5167e](https://github.com/go-redis/redis/commit/7d5167e8624ac1515e146ed183becb97dadb3d1a)) +- **pool:** add check for badConnection + ([a8a7665](https://github.com/go-redis/redis/commit/a8a7665ddf8cc657c5226b1826a8ee83dab4b8c1)), + closes [#2053](https://github.com/go-redis/redis/issues/2053) +- provide a username and password callback method, so that the plaintext username and password will + not be stored in the memory, and the username and password will only be generated once when the + CredentialsProvider is called. After the method is executed, the username and password strings on + the stack will be released. ([#2097](https://github.com/go-redis/redis/issues/2097)) + ([56a3dbc](https://github.com/go-redis/redis/commit/56a3dbc7b656525eb88e0735e239d56e04a23bee)) +- upgrade to Redis 7 + ([d09c27e](https://github.com/go-redis/redis/commit/d09c27e6046129fd27b1d275e5a13a477bd7f778)) ## v9 UNRELEASED @@ -29,3 +46,7 @@ - Removed `Pipeline.Close` since there is no real need to explicitly manage pipeline resources. `Pipeline.Discard` is still available if you want to reset commands for some reason. - Replaced `*redis.Z` with `redis.Z` since it is small enough to be passed as value. +- Renamed `MaxConnAge` to `ConnMaxLifetime`. +- Renamed `IdleTimeout` to `ConnMaxIdleTime`. +- Removed connection reaper in favor of `MaxIdleConns`. +- Removed `WithContext`. diff --git a/cluster.go b/cluster.go index 2db73bdb76..05b234aacf 100644 --- a/cluster.go +++ b/cluster.go @@ -72,12 +72,12 @@ type ClusterOptions struct { PoolFIFO bool // PoolSize applies per cluster node and not for the whole cluster. - PoolSize int - MinIdleConns int - MaxConnAge time.Duration - PoolTimeout time.Duration - IdleTimeout time.Duration - IdleCheckFrequency time.Duration + PoolSize int + PoolTimeout time.Duration + MinIdleConns int + MaxIdleConns int + ConnMaxIdleTime time.Duration + ConnMaxLifetime time.Duration TLSConfig *tls.Config } @@ -132,8 +132,6 @@ func (opt *ClusterOptions) init() { } func (opt *ClusterOptions) clientOptions() *Options { - const disableIdleCheck = -1 - return &Options{ Dialer: opt.Dialer, OnConnect: opt.OnConnect, @@ -149,13 +147,13 @@ func (opt *ClusterOptions) clientOptions() *Options { ReadTimeout: opt.ReadTimeout, WriteTimeout: opt.WriteTimeout, - PoolFIFO: opt.PoolFIFO, - PoolSize: opt.PoolSize, - MinIdleConns: opt.MinIdleConns, - MaxConnAge: opt.MaxConnAge, - PoolTimeout: opt.PoolTimeout, - IdleTimeout: opt.IdleTimeout, - IdleCheckFrequency: disableIdleCheck, + PoolFIFO: opt.PoolFIFO, + PoolSize: opt.PoolSize, + PoolTimeout: opt.PoolTimeout, + MinIdleConns: opt.MinIdleConns, + MaxIdleConns: opt.MaxIdleConns, + ConnMaxIdleTime: opt.ConnMaxIdleTime, + ConnMaxLifetime: opt.ConnMaxLifetime, TLSConfig: opt.TLSConfig, // If ClusterSlots is populated, then we probably have an artificial @@ -725,10 +723,6 @@ func NewClusterClient(opt *ClusterOptions) *ClusterClient { c.cmdsInfoCache = newCmdsInfoCache(c.cmdsInfo) c.cmdable = c.Process - if opt.IdleCheckFrequency > 0 { - go c.reaper(opt.IdleCheckFrequency) - } - return c } @@ -1049,26 +1043,6 @@ func (c *ClusterClient) loadState(ctx context.Context) (*clusterState, error) { return nil, firstErr } -// reaper closes idle connections to the cluster. -func (c *ClusterClient) reaper(idleCheckFrequency time.Duration) { - ticker := time.NewTicker(idleCheckFrequency) - defer ticker.Stop() - - for range ticker.C { - nodes, err := c.nodes.All() - if err != nil { - break - } - - for _, node := range nodes { - _, err := node.Client.connPool.(*pool.ConnPool).ReapStaleConns() - if err != nil { - internal.Logger.Printf(context.TODO(), "ReapStaleConns failed: %s", err) - } - } - } -} - func (c *ClusterClient) Pipeline() Pipeliner { pipe := Pipeline{ exec: c.processPipeline, diff --git a/internal/pool/bench_test.go b/internal/pool/bench_test.go index 0d8dbbdf77..067ae06cf6 100644 --- a/internal/pool/bench_test.go +++ b/internal/pool/bench_test.go @@ -30,11 +30,10 @@ func BenchmarkPoolGetPut(b *testing.B) { for _, bm := range benchmarks { b.Run(bm.String(), func(b *testing.B) { connPool := pool.NewConnPool(&pool.Options{ - Dialer: dummyDialer, - PoolSize: bm.poolSize, - PoolTimeout: time.Second, - IdleTimeout: time.Hour, - IdleCheckFrequency: time.Hour, + Dialer: dummyDialer, + PoolSize: bm.poolSize, + PoolTimeout: time.Second, + ConnMaxIdleTime: time.Hour, }) b.ResetTimer() @@ -74,11 +73,10 @@ func BenchmarkPoolGetRemove(b *testing.B) { for _, bm := range benchmarks { b.Run(bm.String(), func(b *testing.B) { connPool := pool.NewConnPool(&pool.Options{ - Dialer: dummyDialer, - PoolSize: bm.poolSize, - PoolTimeout: time.Second, - IdleTimeout: time.Hour, - IdleCheckFrequency: time.Hour, + Dialer: dummyDialer, + PoolSize: bm.poolSize, + PoolTimeout: time.Second, + ConnMaxIdleTime: time.Hour, }) b.ResetTimer() diff --git a/internal/pool/conn_check.go b/internal/pool/conn_check.go index 74680e4b39..f04dc1c3ba 100644 --- a/internal/pool/conn_check.go +++ b/internal/pool/conn_check.go @@ -27,7 +27,8 @@ func connCheck(conn net.Conn) error { } var sysErr error - err = rawConn.Read(func(fd uintptr) bool { + + if err := rawConn.Read(func(fd uintptr) bool { var buf [1]byte n, err := syscall.Read(int(fd), buf[:]) switch { @@ -41,8 +42,7 @@ func connCheck(conn net.Conn) error { sysErr = err } return true - }) - if err != nil { + }); err != nil { return err } diff --git a/internal/pool/pool.go b/internal/pool/pool.go index 42fed8e2d0..541ee8d477 100644 --- a/internal/pool/pool.go +++ b/internal/pool/pool.go @@ -57,13 +57,13 @@ type Options struct { Dialer func(context.Context) (net.Conn, error) OnClose func(*Conn) error - PoolFIFO bool - PoolSize int - MinIdleConns int - MaxConnAge time.Duration - PoolTimeout time.Duration - IdleTimeout time.Duration - IdleCheckFrequency time.Duration + PoolFIFO bool + PoolSize int + PoolTimeout time.Duration + MinIdleConns int + MaxIdleConns int + ConnMaxIdleTime time.Duration + ConnMaxLifetime time.Duration } type lastDialErrorWrap struct { @@ -71,17 +71,17 @@ type lastDialErrorWrap struct { } type ConnPool struct { - opt *Options + cfg *Options dialErrorsNum uint32 // atomic - lastDialError atomic.Value queue chan struct{} - connsMu sync.Mutex - conns []*Conn - idleConns []*Conn + connsMu sync.Mutex + conns []*Conn + idleConns []*Conn + poolSize int idleConnsLen int @@ -95,7 +95,7 @@ var _ Pooler = (*ConnPool)(nil) func NewConnPool(opt *Options) *ConnPool { p := &ConnPool{ - opt: opt, + cfg: opt, queue: make(chan struct{}, opt.PoolSize), conns: make([]*Conn, 0, opt.PoolSize), @@ -107,18 +107,14 @@ func NewConnPool(opt *Options) *ConnPool { p.checkMinIdleConns() p.connsMu.Unlock() - if opt.IdleTimeout > 0 && opt.IdleCheckFrequency > 0 { - go p.reaper(opt.IdleCheckFrequency) - } - return p } func (p *ConnPool) checkMinIdleConns() { - if p.opt.MinIdleConns == 0 { + if p.cfg.MinIdleConns == 0 { return } - for p.poolSize < p.opt.PoolSize && p.idleConnsLen < p.opt.MinIdleConns { + for p.poolSize < p.cfg.PoolSize && p.idleConnsLen < p.cfg.MinIdleConns { p.poolSize++ p.idleConnsLen++ @@ -176,7 +172,7 @@ func (p *ConnPool) newConn(ctx context.Context, pooled bool) (*Conn, error) { p.conns = append(p.conns, cn) if pooled { // If pool is full remove the cn on next Put. - if p.poolSize >= p.opt.PoolSize { + if p.poolSize >= p.cfg.PoolSize { cn.pooled = false } else { p.poolSize++ @@ -191,14 +187,14 @@ func (p *ConnPool) dialConn(ctx context.Context, pooled bool) (*Conn, error) { return nil, ErrClosed } - if atomic.LoadUint32(&p.dialErrorsNum) >= uint32(p.opt.PoolSize) { + if atomic.LoadUint32(&p.dialErrorsNum) >= uint32(p.cfg.PoolSize) { return nil, p.getLastDialError() } - netConn, err := p.opt.Dialer(ctx) + netConn, err := p.cfg.Dialer(ctx) if err != nil { p.setLastDialError(err) - if atomic.AddUint32(&p.dialErrorsNum, 1) == uint32(p.opt.PoolSize) { + if atomic.AddUint32(&p.dialErrorsNum, 1) == uint32(p.cfg.PoolSize) { go p.tryDial() } return nil, err @@ -215,7 +211,7 @@ func (p *ConnPool) tryDial() { return } - conn, err := p.opt.Dialer(context.Background()) + conn, err := p.cfg.Dialer(context.Background()) if err != nil { p.setLastDialError(err) time.Sleep(time.Second) @@ -263,7 +259,7 @@ func (p *ConnPool) Get(ctx context.Context) (*Conn, error) { break } - if p.isStaleConn(cn) { + if !p.isHealthyConn(cn) { _ = p.CloseConn(cn) continue } @@ -283,10 +279,6 @@ func (p *ConnPool) Get(ctx context.Context) (*Conn, error) { return newcn, nil } -func (p *ConnPool) getTurn() { - p.queue <- struct{}{} -} - func (p *ConnPool) waitTurn(ctx context.Context) error { select { case <-ctx.Done(): @@ -301,7 +293,7 @@ func (p *ConnPool) waitTurn(ctx context.Context) error { } timer := timers.Get().(*time.Timer) - timer.Reset(p.opt.PoolTimeout) + timer.Reset(p.cfg.PoolTimeout) select { case <-ctx.Done(): @@ -337,7 +329,7 @@ func (p *ConnPool) popIdle() (*Conn, error) { } var cn *Conn - if p.opt.PoolFIFO { + if p.cfg.PoolFIFO { cn = p.idleConns[0] copy(p.idleConns, p.idleConns[1:]) p.idleConns = p.idleConns[:n-1] @@ -363,11 +355,25 @@ func (p *ConnPool) Put(ctx context.Context, cn *Conn) { return } + var shouldCloseConn bool + p.connsMu.Lock() - p.idleConns = append(p.idleConns, cn) - p.idleConnsLen++ + + if p.cfg.MaxIdleConns == 0 || p.idleConnsLen < p.cfg.MaxIdleConns { + p.idleConns = append(p.idleConns, cn) + p.idleConnsLen++ + } else { + p.removeConn(cn) + shouldCloseConn = true + } + p.connsMu.Unlock() + p.freeTurn() + + if shouldCloseConn { + _ = p.closeConn(cn) + } } func (p *ConnPool) Remove(ctx context.Context, cn *Conn, reason error) { @@ -383,8 +389,8 @@ func (p *ConnPool) CloseConn(cn *Conn) error { func (p *ConnPool) removeConnWithLock(cn *Conn) { p.connsMu.Lock() + defer p.connsMu.Unlock() p.removeConn(cn) - p.connsMu.Unlock() } func (p *ConnPool) removeConn(cn *Conn) { @@ -395,14 +401,14 @@ func (p *ConnPool) removeConn(cn *Conn) { p.poolSize-- p.checkMinIdleConns() } - return + break } } } func (p *ConnPool) closeConn(cn *Conn) error { - if p.opt.OnClose != nil { - _ = p.opt.OnClose(cn) + if p.cfg.OnClose != nil { + _ = p.cfg.OnClose(cn) } return cn.Close() } @@ -477,81 +483,21 @@ func (p *ConnPool) Close() error { return firstErr } -func (p *ConnPool) reaper(frequency time.Duration) { - ticker := time.NewTicker(frequency) - defer ticker.Stop() - - for { - select { - case <-ticker.C: - // It is possible that ticker and closedCh arrive together, - // and select pseudo-randomly pick ticker case, we double - // check here to prevent being executed after closed. - if p.closed() { - return - } - _, err := p.ReapStaleConns() - if err != nil { - internal.Logger.Printf(context.Background(), "ReapStaleConns failed: %s", err) - continue - } - case <-p.closedCh: - return - } - } -} - -func (p *ConnPool) ReapStaleConns() (int, error) { - var n int - for { - p.getTurn() - - p.connsMu.Lock() - cn := p.reapStaleConn() - p.connsMu.Unlock() - - p.freeTurn() - - if cn != nil { - _ = p.closeConn(cn) - n++ - } else { - break - } - } - atomic.AddUint32(&p.stats.StaleConns, uint32(n)) - return n, nil -} +func (p *ConnPool) isHealthyConn(cn *Conn) bool { + now := time.Now() -func (p *ConnPool) reapStaleConn() *Conn { - if len(p.idleConns) == 0 { - return nil + if p.cfg.ConnMaxLifetime > 0 && now.Sub(cn.createdAt) >= p.cfg.ConnMaxLifetime { + return false } - - cn := p.idleConns[0] - if !p.isStaleConn(cn) { - return nil + if p.cfg.ConnMaxIdleTime > 0 && now.Sub(cn.UsedAt()) >= p.cfg.ConnMaxIdleTime { + atomic.AddUint32(&p.stats.IdleConns, 1) + return false } - p.idleConns = append(p.idleConns[:0], p.idleConns[1:]...) - p.idleConnsLen-- - p.removeConn(cn) - - return cn -} - -func (p *ConnPool) isStaleConn(cn *Conn) bool { - if p.opt.IdleTimeout == 0 && p.opt.MaxConnAge == 0 { - return connCheck(cn.netConn) != nil - } - - now := time.Now() - if p.opt.IdleTimeout > 0 && now.Sub(cn.UsedAt()) >= p.opt.IdleTimeout { - return true - } - if p.opt.MaxConnAge > 0 && now.Sub(cn.createdAt) >= p.opt.MaxConnAge { - return true + if connCheck(cn.netConn) != nil { + return false } - return connCheck(cn.netConn) != nil + cn.SetUsedAt(now) + return true } diff --git a/internal/pool/pool_test.go b/internal/pool/pool_test.go index e1e89f44ba..23a13af73a 100644 --- a/internal/pool/pool_test.go +++ b/internal/pool/pool_test.go @@ -19,11 +19,10 @@ var _ = Describe("ConnPool", func() { BeforeEach(func() { connPool = pool.NewConnPool(&pool.Options{ - Dialer: dummyDialer, - PoolSize: 10, - PoolTimeout: time.Hour, - IdleTimeout: time.Millisecond, - IdleCheckFrequency: time.Millisecond, + Dialer: dummyDialer, + PoolSize: 10, + PoolTimeout: time.Hour, + ConnMaxIdleTime: time.Millisecond, }) }) @@ -45,11 +44,10 @@ var _ = Describe("ConnPool", func() { <-closedChan return &net.TCPConn{}, nil }, - PoolSize: 10, - PoolTimeout: time.Hour, - IdleTimeout: time.Millisecond, - IdleCheckFrequency: time.Millisecond, - MinIdleConns: minIdleConns, + PoolSize: 10, + PoolTimeout: time.Hour, + ConnMaxIdleTime: time.Millisecond, + MinIdleConns: minIdleConns, }) wg.Wait() Expect(connPool.Close()).NotTo(HaveOccurred()) @@ -127,12 +125,11 @@ var _ = Describe("MinIdleConns", func() { newConnPool := func() *pool.ConnPool { connPool := pool.NewConnPool(&pool.Options{ - Dialer: dummyDialer, - PoolSize: poolSize, - MinIdleConns: minIdleConns, - PoolTimeout: 100 * time.Millisecond, - IdleTimeout: -1, - IdleCheckFrequency: -1, + Dialer: dummyDialer, + PoolSize: poolSize, + MinIdleConns: minIdleConns, + PoolTimeout: 100 * time.Millisecond, + ConnMaxIdleTime: -1, }) Eventually(func() int { return connPool.Len() @@ -287,133 +284,6 @@ var _ = Describe("MinIdleConns", func() { }) }) -var _ = Describe("conns reaper", func() { - const idleTimeout = time.Minute - const maxAge = time.Hour - - ctx := context.Background() - var connPool *pool.ConnPool - var conns, staleConns, closedConns []*pool.Conn - - assert := func(typ string) { - BeforeEach(func() { - closedConns = nil - connPool = pool.NewConnPool(&pool.Options{ - Dialer: dummyDialer, - PoolSize: 10, - IdleTimeout: idleTimeout, - MaxConnAge: maxAge, - PoolTimeout: time.Second, - IdleCheckFrequency: time.Hour, - OnClose: func(cn *pool.Conn) error { - closedConns = append(closedConns, cn) - return nil - }, - }) - - conns = nil - - // add stale connections - staleConns = nil - for i := 0; i < 3; i++ { - cn, err := connPool.Get(ctx) - Expect(err).NotTo(HaveOccurred()) - switch typ { - case "idle": - cn.SetUsedAt(time.Now().Add(-2 * idleTimeout)) - case "aged": - cn.SetCreatedAt(time.Now().Add(-2 * maxAge)) - case "connCheck": - _ = cn.Close() - } - conns = append(conns, cn) - staleConns = append(staleConns, cn) - } - - // add fresh connections - for i := 0; i < 3; i++ { - cn, err := connPool.Get(ctx) - Expect(err).NotTo(HaveOccurred()) - conns = append(conns, cn) - } - - for _, cn := range conns { - connPool.Put(ctx, cn) - } - - Expect(connPool.Len()).To(Equal(6)) - Expect(connPool.IdleLen()).To(Equal(6)) - - n, err := connPool.ReapStaleConns() - Expect(err).NotTo(HaveOccurred()) - Expect(n).To(Equal(3)) - }) - - AfterEach(func() { - _ = connPool.Close() - Expect(connPool.Len()).To(Equal(0)) - Expect(connPool.IdleLen()).To(Equal(0)) - Expect(len(closedConns)).To(Equal(len(conns))) - Expect(closedConns).To(ConsistOf(conns)) - }) - - It("reaps stale connections", func() { - Expect(connPool.Len()).To(Equal(3)) - Expect(connPool.IdleLen()).To(Equal(3)) - }) - - It("does not reap fresh connections", func() { - n, err := connPool.ReapStaleConns() - Expect(err).NotTo(HaveOccurred()) - Expect(n).To(Equal(0)) - }) - - It("stale connections are closed", func() { - Expect(len(closedConns)).To(Equal(len(staleConns))) - Expect(closedConns).To(ConsistOf(staleConns)) - }) - - It("pool is functional", func() { - for j := 0; j < 3; j++ { - var freeCns []*pool.Conn - for i := 0; i < 3; i++ { - cn, err := connPool.Get(ctx) - Expect(err).NotTo(HaveOccurred()) - Expect(cn).NotTo(BeNil()) - freeCns = append(freeCns, cn) - } - - Expect(connPool.Len()).To(Equal(3)) - Expect(connPool.IdleLen()).To(Equal(0)) - - cn, err := connPool.Get(ctx) - Expect(err).NotTo(HaveOccurred()) - Expect(cn).NotTo(BeNil()) - conns = append(conns, cn) - - Expect(connPool.Len()).To(Equal(4)) - Expect(connPool.IdleLen()).To(Equal(0)) - - connPool.Remove(ctx, cn, nil) - - Expect(connPool.Len()).To(Equal(3)) - Expect(connPool.IdleLen()).To(Equal(0)) - - for _, cn := range freeCns { - connPool.Put(ctx, cn) - } - - Expect(connPool.Len()).To(Equal(3)) - Expect(connPool.IdleLen()).To(Equal(3)) - } - }) - } - - assert("idle") - assert("aged") - assert("connCheck") -}) - var _ = Describe("race", func() { ctx := context.Background() var connPool *pool.ConnPool @@ -433,11 +303,10 @@ var _ = Describe("race", func() { It("does not happen on Get, Put, and Remove", func() { connPool = pool.NewConnPool(&pool.Options{ - Dialer: dummyDialer, - PoolSize: 10, - PoolTimeout: time.Minute, - IdleTimeout: time.Millisecond, - IdleCheckFrequency: time.Millisecond, + Dialer: dummyDialer, + PoolSize: 10, + PoolTimeout: time.Minute, + ConnMaxIdleTime: time.Millisecond, }) perform(C, func(id int) { diff --git a/main_test.go b/main_test.go index 7a80e9d264..24ba02ec4d 100644 --- a/main_test.go +++ b/main_test.go @@ -130,10 +130,9 @@ func redisOptions() *redis.Options { MaxRetries: -1, - PoolSize: 10, - PoolTimeout: 30 * time.Second, - IdleTimeout: time.Minute, - IdleCheckFrequency: 100 * time.Millisecond, + PoolSize: 10, + PoolTimeout: 30 * time.Second, + ConnMaxIdleTime: time.Minute, } } @@ -145,10 +144,9 @@ func redisClusterOptions() *redis.ClusterOptions { MaxRedirects: 8, - PoolSize: 10, - PoolTimeout: 30 * time.Second, - IdleTimeout: time.Minute, - IdleCheckFrequency: 100 * time.Millisecond, + PoolSize: 10, + PoolTimeout: 30 * time.Second, + ConnMaxIdleTime: time.Minute, } } @@ -165,10 +163,9 @@ func redisRingOptions() *redis.RingOptions { MaxRetries: -1, - PoolSize: 10, - PoolTimeout: 30 * time.Second, - IdleTimeout: time.Minute, - IdleCheckFrequency: 100 * time.Millisecond, + PoolSize: 10, + PoolTimeout: 30 * time.Second, + ConnMaxIdleTime: time.Minute, } } diff --git a/options.go b/options.go index 99cfddbbaf..8f5f380fc9 100644 --- a/options.go +++ b/options.go @@ -87,25 +87,22 @@ type Options struct { // Maximum number of socket connections. // Default is 10 connections per every available CPU as reported by runtime.GOMAXPROCS. PoolSize int - // Minimum number of idle connections which is useful when establishing - // new connection is slow. - MinIdleConns int - // Connection age at which client retires (closes) the connection. - // Default is to not close aged connections. - MaxConnAge time.Duration // Amount of time client waits for connection if all connections // are busy before returning an error. // Default is ReadTimeout + 1 second. PoolTimeout time.Duration + // Minimum number of idle connections which is useful when establishing + // new connection is slow. + MinIdleConns int + // Maximum number of idle connections. + MaxIdleConns int // Amount of time after which client closes idle connections. // Should be less than server's timeout. // Default is 5 minutes. -1 disables idle timeout check. - IdleTimeout time.Duration - // Frequency of idle checks made by idle connections reaper. - // Default is 1 minute. -1 disables idle connections reaper, - // but idle connections are still discarded by the client - // if IdleTimeout is set. - IdleCheckFrequency time.Duration + ConnMaxIdleTime time.Duration + // Connection age at which client retires (closes) the connection. + // Default is to not close aged connections. + ConnMaxLifetime time.Duration // Enables read only queries on slave nodes. readOnly bool @@ -161,11 +158,8 @@ func (opt *Options) init() { if opt.PoolTimeout == 0 { opt.PoolTimeout = opt.ReadTimeout + time.Second } - if opt.IdleTimeout == 0 { - opt.IdleTimeout = 5 * time.Minute - } - if opt.IdleCheckFrequency == 0 { - opt.IdleCheckFrequency = time.Minute + if opt.ConnMaxIdleTime == 0 { + opt.ConnMaxIdleTime = 30 * time.Minute } if opt.MaxRetries == -1 { @@ -297,6 +291,10 @@ type queryOptions struct { err error } +func (o *queryOptions) has(name string) bool { + return len(o.q[name]) > 0 +} + func (o *queryOptions) string(name string) string { vs := o.q[name] if len(vs) == 0 { @@ -391,11 +389,19 @@ func setupConnParams(u *url.URL, o *Options) (*Options, error) { o.WriteTimeout = q.duration("write_timeout") o.PoolFIFO = q.bool("pool_fifo") o.PoolSize = q.int("pool_size") - o.MinIdleConns = q.int("min_idle_conns") - o.MaxConnAge = q.duration("max_conn_age") o.PoolTimeout = q.duration("pool_timeout") - o.IdleTimeout = q.duration("idle_timeout") - o.IdleCheckFrequency = q.duration("idle_check_frequency") + o.MinIdleConns = q.int("min_idle_conns") + o.MaxIdleConns = q.int("max_idle_conns") + if q.has("conn_max_idle_time") { + o.ConnMaxIdleTime = q.duration("conn_max_idle_time") + } else { + o.ConnMaxIdleTime = q.duration("idle_timeout") + } + if q.has("conn_max_lifetime") { + o.ConnMaxLifetime = q.duration("conn_max_lifetime") + } else { + o.ConnMaxLifetime = q.duration("max_conn_age") + } if q.err != nil { return nil, q.err } @@ -424,12 +430,12 @@ func newConnPool(opt *Options) *pool.ConnPool { Dialer: func(ctx context.Context) (net.Conn, error) { return opt.Dialer(ctx, opt.Network, opt.Addr) }, - PoolFIFO: opt.PoolFIFO, - PoolSize: opt.PoolSize, - MinIdleConns: opt.MinIdleConns, - MaxConnAge: opt.MaxConnAge, - PoolTimeout: opt.PoolTimeout, - IdleTimeout: opt.IdleTimeout, - IdleCheckFrequency: opt.IdleCheckFrequency, + PoolFIFO: opt.PoolFIFO, + PoolSize: opt.PoolSize, + PoolTimeout: opt.PoolTimeout, + MinIdleConns: opt.MinIdleConns, + MaxIdleConns: opt.MaxIdleConns, + ConnMaxIdleTime: opt.ConnMaxIdleTime, + ConnMaxLifetime: opt.ConnMaxLifetime, }) } diff --git a/options_test.go b/options_test.go index 145052394a..f9c69a480b 100644 --- a/options_test.go +++ b/options_test.go @@ -47,18 +47,18 @@ func TestParseURL(t *testing.T) { }, { // special case handling for disabled timeouts url: "redis://localhost:123/?db=2&idle_timeout=0", - o: &Options{Addr: "localhost:123", DB: 2, IdleTimeout: -1}, + o: &Options{Addr: "localhost:123", DB: 2, ConnMaxIdleTime: -1}, }, { // negative values disable timeouts as well url: "redis://localhost:123/?db=2&idle_timeout=-1", - o: &Options{Addr: "localhost:123", DB: 2, IdleTimeout: -1}, + o: &Options{Addr: "localhost:123", DB: 2, ConnMaxIdleTime: -1}, }, { // absent timeout values will use defaults url: "redis://localhost:123/?db=2&idle_timeout=", - o: &Options{Addr: "localhost:123", DB: 2, IdleTimeout: 0}, + o: &Options{Addr: "localhost:123", DB: 2, ConnMaxIdleTime: 0}, }, { url: "redis://localhost:123/?db=2&idle_timeout", // missing "=" at the end - o: &Options{Addr: "localhost:123", DB: 2, IdleTimeout: 0}, + o: &Options{Addr: "localhost:123", DB: 2, ConnMaxIdleTime: 0}, }, { url: "unix:///tmp/redis.sock", o: &Options{Addr: "/tmp/redis.sock"}, @@ -174,20 +174,20 @@ func comprareOptions(t *testing.T, actual, expected *Options) { if actual.PoolSize != expected.PoolSize { t.Errorf("PoolSize: got %v, expected %v", actual.PoolSize, expected.PoolSize) } + if actual.PoolTimeout != expected.PoolTimeout { + t.Errorf("PoolTimeout: got %v, expected %v", actual.PoolTimeout, expected.PoolTimeout) + } if actual.MinIdleConns != expected.MinIdleConns { t.Errorf("MinIdleConns: got %v, expected %v", actual.MinIdleConns, expected.MinIdleConns) } - if actual.MaxConnAge != expected.MaxConnAge { - t.Errorf("MaxConnAge: got %v, expected %v", actual.MaxConnAge, expected.MaxConnAge) - } - if actual.PoolTimeout != expected.PoolTimeout { - t.Errorf("PoolTimeout: got %v, expected %v", actual.PoolTimeout, expected.PoolTimeout) + if actual.MaxIdleConns != expected.MaxIdleConns { + t.Errorf("MaxIdleConns: got %v, expected %v", actual.MaxIdleConns, expected.MaxIdleConns) } - if actual.IdleTimeout != expected.IdleTimeout { - t.Errorf("IdleTimeout: got %v, expected %v", actual.IdleTimeout, expected.IdleTimeout) + if actual.ConnMaxIdleTime != expected.ConnMaxIdleTime { + t.Errorf("ConnMaxIdleTime: got %v, expected %v", actual.ConnMaxIdleTime, expected.ConnMaxIdleTime) } - if actual.IdleCheckFrequency != expected.IdleCheckFrequency { - t.Errorf("IdleCheckFrequency: got %v, expected %v", actual.IdleCheckFrequency, expected.IdleCheckFrequency) + if actual.ConnMaxLifetime != expected.ConnMaxLifetime { + t.Errorf("ConnMaxLifetime: got %v, expected %v", actual.ConnMaxLifetime, expected.ConnMaxLifetime) } } diff --git a/pool_test.go b/pool_test.go index a45b3de4be..2a22edd38b 100644 --- a/pool_test.go +++ b/pool_test.go @@ -16,8 +16,8 @@ var _ = Describe("pool", func() { BeforeEach(func() { opt := redisOptions() opt.MinIdleConns = 0 - opt.MaxConnAge = 0 - opt.IdleTimeout = time.Second + opt.ConnMaxLifetime = 0 + opt.ConnMaxIdleTime = time.Second client = redis.NewClient(opt) }) @@ -108,8 +108,8 @@ var _ = Describe("pool", func() { // explain: https://github.com/go-redis/redis/pull/1675 opt := redisOptions() opt.MinIdleConns = 0 - opt.MaxConnAge = 0 - opt.IdleTimeout = 2 * time.Second + opt.ConnMaxLifetime = 0 + opt.ConnMaxIdleTime = 10 * time.Second client = redis.NewClient(opt) for i := 0; i < 100; i++ { @@ -127,31 +127,4 @@ var _ = Describe("pool", func() { Expect(stats.Misses).To(Equal(uint32(1))) Expect(stats.Timeouts).To(Equal(uint32(0))) }) - - It("removes idle connections", func() { - err := client.Ping(ctx).Err() - Expect(err).NotTo(HaveOccurred()) - - stats := client.PoolStats() - Expect(stats).To(Equal(&redis.PoolStats{ - Hits: 0, - Misses: 1, - Timeouts: 0, - TotalConns: 1, - IdleConns: 1, - StaleConns: 0, - })) - - time.Sleep(2 * time.Second) - - stats = client.PoolStats() - Expect(stats).To(Equal(&redis.PoolStats{ - Hits: 0, - Misses: 1, - Timeouts: 0, - TotalConns: 0, - IdleConns: 0, - StaleConns: 1, - })) - }) }) diff --git a/pubsub_test.go b/pubsub_test.go index 6777ec67ea..892118e02c 100644 --- a/pubsub_test.go +++ b/pubsub_test.go @@ -18,7 +18,7 @@ var _ = Describe("PubSub", func() { BeforeEach(func() { opt := redisOptions() opt.MinIdleConns = 0 - opt.MaxConnAge = 0 + opt.ConnMaxLifetime = 0 client = redis.NewClient(opt) Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred()) }) diff --git a/ring.go b/ring.go index cdb429a93e..dede1e4959 100644 --- a/ring.go +++ b/ring.go @@ -82,12 +82,12 @@ type RingOptions struct { // PoolFIFO uses FIFO mode for each node connection pool GET/PUT (default LIFO). PoolFIFO bool - PoolSize int - MinIdleConns int - MaxConnAge time.Duration - PoolTimeout time.Duration - IdleTimeout time.Duration - IdleCheckFrequency time.Duration + PoolSize int + PoolTimeout time.Duration + MinIdleConns int + MaxIdleConns int + ConnMaxIdleTime time.Duration + ConnMaxLifetime time.Duration TLSConfig *tls.Config Limiter Limiter @@ -142,13 +142,13 @@ func (opt *RingOptions) clientOptions() *Options { ReadTimeout: opt.ReadTimeout, WriteTimeout: opt.WriteTimeout, - PoolFIFO: opt.PoolFIFO, - PoolSize: opt.PoolSize, - MinIdleConns: opt.MinIdleConns, - MaxConnAge: opt.MaxConnAge, - PoolTimeout: opt.PoolTimeout, - IdleTimeout: opt.IdleTimeout, - IdleCheckFrequency: opt.IdleCheckFrequency, + PoolFIFO: opt.PoolFIFO, + PoolSize: opt.PoolSize, + PoolTimeout: opt.PoolTimeout, + MinIdleConns: opt.MinIdleConns, + MaxIdleConns: opt.MaxIdleConns, + ConnMaxIdleTime: opt.ConnMaxIdleTime, + ConnMaxLifetime: opt.ConnMaxLifetime, TLSConfig: opt.TLSConfig, Limiter: opt.Limiter, diff --git a/sentinel.go b/sentinel.go index f318e0fe38..a2dbcce4ec 100644 --- a/sentinel.go +++ b/sentinel.go @@ -63,15 +63,14 @@ type FailoverOptions struct { ReadTimeout time.Duration WriteTimeout time.Duration - // PoolFIFO uses FIFO mode for each node connection pool GET/PUT (default LIFO). PoolFIFO bool - PoolSize int - MinIdleConns int - MaxConnAge time.Duration - PoolTimeout time.Duration - IdleTimeout time.Duration - IdleCheckFrequency time.Duration + PoolSize int + PoolTimeout time.Duration + MinIdleConns int + MaxIdleConns int + ConnMaxIdleTime time.Duration + ConnMaxLifetime time.Duration TLSConfig *tls.Config } @@ -95,13 +94,13 @@ func (opt *FailoverOptions) clientOptions() *Options { ReadTimeout: opt.ReadTimeout, WriteTimeout: opt.WriteTimeout, - PoolFIFO: opt.PoolFIFO, - PoolSize: opt.PoolSize, - PoolTimeout: opt.PoolTimeout, - IdleTimeout: opt.IdleTimeout, - IdleCheckFrequency: opt.IdleCheckFrequency, - MinIdleConns: opt.MinIdleConns, - MaxConnAge: opt.MaxConnAge, + PoolFIFO: opt.PoolFIFO, + PoolSize: opt.PoolSize, + PoolTimeout: opt.PoolTimeout, + MinIdleConns: opt.MinIdleConns, + MaxIdleConns: opt.MaxIdleConns, + ConnMaxIdleTime: opt.ConnMaxIdleTime, + ConnMaxLifetime: opt.ConnMaxLifetime, TLSConfig: opt.TLSConfig, } @@ -126,13 +125,13 @@ func (opt *FailoverOptions) sentinelOptions(addr string) *Options { ReadTimeout: opt.ReadTimeout, WriteTimeout: opt.WriteTimeout, - PoolFIFO: opt.PoolFIFO, - PoolSize: opt.PoolSize, - PoolTimeout: opt.PoolTimeout, - IdleTimeout: opt.IdleTimeout, - IdleCheckFrequency: opt.IdleCheckFrequency, - MinIdleConns: opt.MinIdleConns, - MaxConnAge: opt.MaxConnAge, + PoolFIFO: opt.PoolFIFO, + PoolSize: opt.PoolSize, + PoolTimeout: opt.PoolTimeout, + MinIdleConns: opt.MinIdleConns, + MaxIdleConns: opt.MaxIdleConns, + ConnMaxIdleTime: opt.ConnMaxIdleTime, + ConnMaxLifetime: opt.ConnMaxLifetime, TLSConfig: opt.TLSConfig, } @@ -158,13 +157,13 @@ func (opt *FailoverOptions) clusterOptions() *ClusterOptions { ReadTimeout: opt.ReadTimeout, WriteTimeout: opt.WriteTimeout, - PoolFIFO: opt.PoolFIFO, - PoolSize: opt.PoolSize, - PoolTimeout: opt.PoolTimeout, - IdleTimeout: opt.IdleTimeout, - IdleCheckFrequency: opt.IdleCheckFrequency, - MinIdleConns: opt.MinIdleConns, - MaxConnAge: opt.MaxConnAge, + PoolFIFO: opt.PoolFIFO, + PoolSize: opt.PoolSize, + PoolTimeout: opt.PoolTimeout, + MinIdleConns: opt.MinIdleConns, + MaxIdleConns: opt.MaxIdleConns, + ConnMaxIdleTime: opt.ConnMaxIdleTime, + ConnMaxLifetime: opt.ConnMaxLifetime, TLSConfig: opt.TLSConfig, } @@ -580,7 +579,7 @@ func (c *sentinelFailover) getReplicaAddrs(ctx context.Context, sentinel *Sentin if err != nil { internal.Logger.Printf(ctx, "sentinel: Replicas name=%q failed: %s", c.opt.MasterName, err) - return []string{} + return nil } return parseReplicaAddrs(addrs, false) } diff --git a/universal.go b/universal.go index 257a205596..a3c5b9d0a1 100644 --- a/universal.go +++ b/universal.go @@ -39,12 +39,12 @@ type UniversalOptions struct { // PoolFIFO uses FIFO mode for each node connection pool GET/PUT (default LIFO). PoolFIFO bool - PoolSize int - MinIdleConns int - MaxConnAge time.Duration - PoolTimeout time.Duration - IdleTimeout time.Duration - IdleCheckFrequency time.Duration + PoolSize int + PoolTimeout time.Duration + MinIdleConns int + MaxIdleConns int + ConnMaxIdleTime time.Duration + ConnMaxLifetime time.Duration TLSConfig *tls.Config @@ -84,16 +84,18 @@ func (o *UniversalOptions) Cluster() *ClusterOptions { MinRetryBackoff: o.MinRetryBackoff, MaxRetryBackoff: o.MaxRetryBackoff, - DialTimeout: o.DialTimeout, - ReadTimeout: o.ReadTimeout, - WriteTimeout: o.WriteTimeout, - PoolFIFO: o.PoolFIFO, - PoolSize: o.PoolSize, - MinIdleConns: o.MinIdleConns, - MaxConnAge: o.MaxConnAge, - PoolTimeout: o.PoolTimeout, - IdleTimeout: o.IdleTimeout, - IdleCheckFrequency: o.IdleCheckFrequency, + DialTimeout: o.DialTimeout, + ReadTimeout: o.ReadTimeout, + WriteTimeout: o.WriteTimeout, + + PoolFIFO: o.PoolFIFO, + + PoolSize: o.PoolSize, + PoolTimeout: o.PoolTimeout, + MinIdleConns: o.MinIdleConns, + MaxIdleConns: o.MaxIdleConns, + ConnMaxIdleTime: o.ConnMaxIdleTime, + ConnMaxLifetime: o.ConnMaxLifetime, TLSConfig: o.TLSConfig, } @@ -126,13 +128,13 @@ func (o *UniversalOptions) Failover() *FailoverOptions { ReadTimeout: o.ReadTimeout, WriteTimeout: o.WriteTimeout, - PoolFIFO: o.PoolFIFO, - PoolSize: o.PoolSize, - MinIdleConns: o.MinIdleConns, - MaxConnAge: o.MaxConnAge, - PoolTimeout: o.PoolTimeout, - IdleTimeout: o.IdleTimeout, - IdleCheckFrequency: o.IdleCheckFrequency, + PoolFIFO: o.PoolFIFO, + PoolSize: o.PoolSize, + PoolTimeout: o.PoolTimeout, + MinIdleConns: o.MinIdleConns, + MaxIdleConns: o.MaxIdleConns, + ConnMaxIdleTime: o.ConnMaxIdleTime, + ConnMaxLifetime: o.ConnMaxLifetime, TLSConfig: o.TLSConfig, } @@ -162,13 +164,13 @@ func (o *UniversalOptions) Simple() *Options { ReadTimeout: o.ReadTimeout, WriteTimeout: o.WriteTimeout, - PoolFIFO: o.PoolFIFO, - PoolSize: o.PoolSize, - MinIdleConns: o.MinIdleConns, - MaxConnAge: o.MaxConnAge, - PoolTimeout: o.PoolTimeout, - IdleTimeout: o.IdleTimeout, - IdleCheckFrequency: o.IdleCheckFrequency, + PoolFIFO: o.PoolFIFO, + PoolSize: o.PoolSize, + PoolTimeout: o.PoolTimeout, + MinIdleConns: o.MinIdleConns, + MaxIdleConns: o.MaxIdleConns, + ConnMaxIdleTime: o.ConnMaxIdleTime, + ConnMaxLifetime: o.ConnMaxLifetime, TLSConfig: o.TLSConfig, } From 2e174a228f2c9e729fce676a2e244254b3171295 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Thu, 28 Jul 2022 15:40:09 +0300 Subject: [PATCH 060/621] chore: release v9.0.0-beta.2 (release.sh) --- CHANGELOG.md | 18 ++ example/del-keys-without-ttl/go.mod | 2 +- example/del-keys-without-ttl/go.sum | 31 ++- example/hll/go.mod | 2 +- example/hll/go.sum | 31 ++- example/lua-scripting/go.mod | 2 +- example/lua-scripting/go.sum | 31 ++- example/otel/go.mod | 15 +- example/otel/go.sum | 324 +++++++++++++++++++++++----- example/redis-bloom/go.mod | 2 +- example/redis-bloom/go.sum | 31 ++- example/scan-struct/go.mod | 2 +- example/scan-struct/go.sum | 31 ++- extra/rediscensus/go.mod | 4 +- extra/rediscensus/go.sum | 31 ++- extra/rediscmd/go.mod | 4 +- extra/rediscmd/go.sum | 31 ++- extra/redisotel/go.mod | 8 +- extra/redisotel/go.sum | 40 ++-- package.json | 2 +- version.go | 2 +- 21 files changed, 495 insertions(+), 149 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0350b02c0e..9c18618a8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +# [9.0.0-beta.2](https://github.com/go-redis/redis/compare/v9.0.0-beta.1...v9.0.0-beta.2) (2022-07-28) + + +### Bug Fixes + +* [#2114](https://github.com/go-redis/redis/issues/2114) for redis-server not support Hello ([b6d2a92](https://github.com/go-redis/redis/commit/b6d2a925297e3e516eb5c76c114c1c9fcd5b68c5)) +* additional node failures in clustered pipelined reads ([03376a5](https://github.com/go-redis/redis/commit/03376a5d9c7dfd7197b14ce13b24a0431a07a663)) +* disregard failed pings in updateLatency() for cluster nodes ([64f972f](https://github.com/go-redis/redis/commit/64f972fbeae401e52a2c066a0e1c922af617e15c)) +* don't panic when test cannot start ([9e16c79](https://github.com/go-redis/redis/commit/9e16c79951e7769621b7320f1ecdf04baf539b82)) +* handle panic in ringShards Hash function when Ring got closed ([a80b84f](https://github.com/go-redis/redis/commit/a80b84f01f9fc0d3e6f08445ba21f7e07880775e)), closes [#2126](https://github.com/go-redis/redis/issues/2126) +* ignore Nil error when reading EntriesRead ([89d6dfe](https://github.com/go-redis/redis/commit/89d6dfe09a88321d445858c1c5b24d2757b95a3e)) +* log errors from cmdsInfoCache ([fa4d1ea](https://github.com/go-redis/redis/commit/fa4d1ea8398cd729ad5cbaaff88e4b8805393945)) +* provide a signal channel to end heartbeat goroutine ([f032c12](https://github.com/go-redis/redis/commit/f032c126db3e2c1a239ce1790b0ab81994df75cf)) +* remove conn reaper from the pool and uptrace option names ([f6a8adc](https://github.com/go-redis/redis/commit/f6a8adc50cdaec30527f50d06468f9176ee674fe)) +* replace heartbeat signal channel with context.WithCancel ([20d0ca2](https://github.com/go-redis/redis/commit/20d0ca235efff48ad48cc05b98790b825d4ba979)) + + + # [9.0.0-beta.1](https://github.com/go-redis/redis/compare/v8.11.5...v9.0.0-beta.1) (2022-06-04) ### Bug Fixes diff --git a/example/del-keys-without-ttl/go.mod b/example/del-keys-without-ttl/go.mod index 4a10f38314..51259d7b91 100644 --- a/example/del-keys-without-ttl/go.mod +++ b/example/del-keys-without-ttl/go.mod @@ -4,4 +4,4 @@ go 1.14 replace github.com/go-redis/redis/v9 => ../.. -require github.com/go-redis/redis/v9 v9.0.0-beta.1 +require github.com/go-redis/redis/v9 v9.0.0-beta.2 diff --git a/example/del-keys-without-ttl/go.sum b/example/del-keys-without-ttl/go.sum index f694e5247c..224bfa9034 100644 --- a/example/del-keys-without-ttl/go.sum +++ b/example/del-keys-without-ttl/go.sum @@ -24,8 +24,9 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -37,32 +38,41 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -76,8 +86,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -88,10 +101,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -100,8 +113,9 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -110,5 +124,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/example/hll/go.mod b/example/hll/go.mod index 87d9eab4a6..723ebde8f5 100644 --- a/example/hll/go.mod +++ b/example/hll/go.mod @@ -4,4 +4,4 @@ go 1.14 replace github.com/go-redis/redis/v9 => ../.. -require github.com/go-redis/redis/v9 v9.0.0-beta.1 +require github.com/go-redis/redis/v9 v9.0.0-beta.2 diff --git a/example/hll/go.sum b/example/hll/go.sum index f694e5247c..224bfa9034 100644 --- a/example/hll/go.sum +++ b/example/hll/go.sum @@ -24,8 +24,9 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -37,32 +38,41 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -76,8 +86,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -88,10 +101,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -100,8 +113,9 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -110,5 +124,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/example/lua-scripting/go.mod b/example/lua-scripting/go.mod index 7d25def773..409b38a5c8 100644 --- a/example/lua-scripting/go.mod +++ b/example/lua-scripting/go.mod @@ -4,4 +4,4 @@ go 1.14 replace github.com/go-redis/redis/v9 => ../.. -require github.com/go-redis/redis/v9 v9.0.0-beta.1 +require github.com/go-redis/redis/v9 v9.0.0-beta.2 diff --git a/example/lua-scripting/go.sum b/example/lua-scripting/go.sum index f694e5247c..224bfa9034 100644 --- a/example/lua-scripting/go.sum +++ b/example/lua-scripting/go.sum @@ -24,8 +24,9 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -37,32 +38,41 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -76,8 +86,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -88,10 +101,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -100,8 +113,9 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -110,5 +124,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/example/otel/go.mod b/example/otel/go.mod index f658e652be..9d7af37b8d 100644 --- a/example/otel/go.mod +++ b/example/otel/go.mod @@ -9,13 +9,10 @@ replace github.com/go-redis/redis/extra/redisotel/v9 => ../../extra/redisotel replace github.com/go-redis/redis/extra/rediscmd/v9 => ../../extra/rediscmd require ( - github.com/go-redis/redis/extra/rediscmd/v9 v9.0.0-beta.1 // indirect - github.com/go-redis/redis/extra/redisotel/v9 v9.0.0-beta.1 - github.com/go-redis/redis/v9 v9.0.0-beta.1 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3 // indirect - github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.14 - go.opentelemetry.io/otel v1.7.0 - golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect - google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8 // indirect - google.golang.org/grpc v1.47.0 // indirect + github.com/go-redis/redis/extra/redisotel/v9 v9.0.0-beta.2 + github.com/go-redis/redis/v9 v9.0.0-beta.2 + github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.15 + go.opentelemetry.io/otel v1.8.0 + golang.org/x/net v0.0.0-20220728030405-41545e8bf201 // indirect + google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b // indirect ) diff --git a/example/otel/go.sum b/example/otel/go.sum index f3598e0761..1466ca30e1 100644 --- a/example/otel/go.sum +++ b/example/otel/go.sum @@ -13,14 +13,36 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -30,6 +52,7 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -50,6 +73,7 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= @@ -65,7 +89,9 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= @@ -96,6 +122,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -111,8 +139,10 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -122,6 +152,9 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= @@ -129,6 +162,8 @@ github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -136,18 +171,30 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.0/go.mod h1:XnLCLFp3tjoZJszVKjfpyAK6J8sYIcQXWQxmqLWF21I= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.2/go.mod h1:chrfS3YoLAlKTRE5cFWvCbt8uGAjshktT4PveTUpsFQ= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3 h1:BGNSrTRW4rwfhJiFwvwF4XQ0Y72Jj9YEgxVrtovbD5o= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3/go.mod h1:VHn7KgNsRriXa4mcgtkpR00OXyQY6g67JWMvn+R27A4= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.0 h1:Ghn7copILfeIg0y8sTGRppI1bd8I4l2VN3cob0Xeqwg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.0/go.mod h1:dnjr4snxnhRSn5GWqJUva2AoMbeaxyAcepvc0Tg8lXk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -170,72 +217,80 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.14 h1:De0aL20N/6OKEhVriq+emXsETL0ZuAEXNlz74O5aTD0= -github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.14/go.mod h1:XZvp41aATsghUfehYGsi2/nEY2BmwgWU9QpXnQvqbR8= -github.com/uptrace/uptrace-go v1.7.1 h1:08V74pATGYoJK+t94oRH6fdaLhs+r8rGWZOk4U6Yl40= -github.com/uptrace/uptrace-go v1.7.1/go.mod h1:ZEFBLqjLJplFeak8w4IrpzDtXd+dY8QhCyHHCL6VP90= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.15 h1:WM1i3KEEPq43C+bj/NZnyvZciB+UFxqPpRWmU24mZJE= +github.com/uptrace/opentelemetry-go-extra/otelplay v0.1.15/go.mod h1:Fmhh1gkFHgadUCj+wN/ySiKPHKrwcLT0tWlTkji6dkc= +github.com/uptrace/uptrace-go v1.8.1 h1:LT8HUVquk5JIW3drk8Cy056vAbtUNRuqEBqn919IpfM= +github.com/uptrace/uptrace-go v1.8.1/go.mod h1:mtxXilGiIBVGuffhwKYRZpmWSZWxtTYyQRzueGR4XSg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/contrib/instrumentation/runtime v0.32.0 h1:eMQf85EgNd2YWEikRJwEy4ADOiwlIum4rcHcssB4Qzk= -go.opentelemetry.io/contrib/instrumentation/runtime v0.32.0/go.mod h1:qtaLlIO4HC4DfedkYTOrvS2u7nA3N/v8w9mehrBD4O8= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/contrib/instrumentation/runtime v0.33.0 h1:YhjJQGhEoxXXKwH16MQEW37KgdZSACk+HyHnFtv/NcI= +go.opentelemetry.io/contrib/instrumentation/runtime v0.33.0/go.mod h1:cu2qiP1YaeuJtMVDUuMJZPfCBqJr4GB9kkwXbg5knMA= go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4= -go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= -go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= -go.opentelemetry.io/otel/exporters/jaeger v1.7.0 h1:wXgjiRldljksZkZrldGVe6XrG9u3kYDyQmkZwmm5dI0= -go.opentelemetry.io/otel/exporters/jaeger v1.7.0/go.mod h1:PwQAOqBgqbLQRKlj466DuD2qyMjbtcPpfPfj+AqbSBs= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 h1:7Yxsak1q4XrJ5y7XBnNwqWx9amMZvoidCctv62XOQ6Y= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0/go.mod h1:M1hVZHNxcbkAlcvrOMlpQ4YOO3Awf+4N2dxkZL3xm04= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.30.0 h1:Os0ds8fJp2AUa9DNraFWIycgUzevz47i6UvnSh+8LQ0= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.30.0/go.mod h1:8Lz1GGcrx1kPGE3zqDrK7ZcPzABEfIQqBjq7roQa5ZA= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.30.0 h1:7E8znQuiqnaFDDl1zJYUpoqHteZI6u2rrcxH3Gwoiis= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.30.0/go.mod h1:RejW0QAFotPIixlFZKZka4/70S5UaFOqDO9DYOgScIs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 h1:cMDtmgJ5FpRvqx9x2Aq+Mm0O6K/zcUkH73SFz20TuBw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0/go.mod h1:ceUgdyfNv4h4gLxHR0WNfDiiVmZFodZhZSbOLhpxqXE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 h1:MFAyzUPrTwLOwCi+cltN0ZVyy4phU41lwH+lyMyQTS4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0/go.mod h1:E+/KKhwOSw8yoPxSSuUHG6vKppkvhN+S1Jc7Nib3k3o= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 h1:8hPcgCg0rUJiKE6VWahRvjgLUrNl7rW2hffUEPKXVEM= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0/go.mod h1:K4GDXPY6TjUiwbOh+DkKaEdCF8y+lvMoM6SeAPyfCCM= -go.opentelemetry.io/otel/metric v0.30.0 h1:Hs8eQZ8aQgs0U49diZoaS6Uaxw3+bBE3lcMUKBFIk3c= -go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU= +go.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg= +go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= +go.opentelemetry.io/otel/exporters/jaeger v1.8.0 h1:TLLqD6kDhLPziEC7pgPrMvP9lAqdk3n1gf8DiFSnfW8= +go.opentelemetry.io/otel/exporters/jaeger v1.8.0/go.mod h1:GbWg+ng88rDtx+id26C34QLqw2erqJeAjsCx9AFeHfE= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.8.0 h1:ao8CJIShCaIbaMsGxy+jp2YHSudketpDgDRcbirov78= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.8.0/go.mod h1:78XhIg8Ht9vR4tbLNUhXsiOnE2HOuSeKAiAcoVQEpOY= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.31.0 h1:H0+xwv4shKw0gfj/ZqR13qO2N/dBQogB1OcRjJjV39Y= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.31.0/go.mod h1:nkenGD8vcvs0uN6WhR90ZVHQlgDsRmXicnNadMnk+XQ= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.31.0 h1:BaQ2xM5cPmldVCMvbLoy5tcLUhXCtIhItDYBNw83B7Y= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.31.0/go.mod h1:VRr8tlXQEsTdesDCh0qBe2iKDWhpi3ZqDYw6VlZ8MhI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.8.0 h1:LrHL1A3KqIgAgi6mK7Q0aczmzU414AONAGT5xtnp+uo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.8.0/go.mod h1:w8aZL87GMOvOBa2lU/JlVXE1q4chk/0FX+8ai4513bw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.8.0 h1:00hCSGLIxdYK/Z7r8GkaX0QIlfvgU3tmnLlQvcnix6U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.8.0/go.mod h1:twhIvtDQW2sWP1O2cT1N8nkSBgKCRZv2z6COTTBrf8Q= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.8.0 h1:FVy7BZCjoA2Nk+fHqIdoTmm554J9wTX+YcrDp+mc368= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.8.0/go.mod h1:ztncjvKpotSUQq7rlgPibGt8kZfSI3/jI8EO7JjuY2c= +go.opentelemetry.io/otel/metric v0.31.0 h1:6SiklT+gfWAwWUR0meEMxQBtihpiEs4c+vL9spDTqUs= +go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A= go.opentelemetry.io/otel/sdk v1.4.1/go.mod h1:NBwHDgDIBYjwK2WNu1OPgsIc2IJzmBXNnvIJxJc8BpE= -go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= -go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= -go.opentelemetry.io/otel/sdk/metric v0.30.0 h1:XTqQ4y3erR2Oj8xSAOL5ovO5011ch2ELg51z4fVkpME= -go.opentelemetry.io/otel/sdk/metric v0.30.0/go.mod h1:8AKFRi5HyvTR0RRty3paN1aMC9HMT+NzcEhw/BLkLX8= +go.opentelemetry.io/otel/sdk v1.8.0 h1:xwu69/fNuwbSHWe/0PGS888RmjWY181OmcXDQKu7ZQk= +go.opentelemetry.io/otel/sdk v1.8.0/go.mod h1:uPSfc+yfDH2StDM/Rm35WE8gXSNdvCg023J6HeGNO0c= +go.opentelemetry.io/otel/sdk/metric v0.31.0 h1:2sZx4R43ZMhJdteKAlKoHvRgrMp53V1aRxvEf5lCq8Q= +go.opentelemetry.io/otel/sdk/metric v0.31.0/go.mod h1:fl0SmNnX9mN9xgU6OLYLMBMrNAsaZQi7qBwprwO3abk= go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc= -go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= -go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= +go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY= +go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.16.0 h1:WHzDWdXUvbc5bG2ObdrGfaNpQz7ft7QN9HHmJlbiB1E= -go.opentelemetry.io/proto/otlp v0.16.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.18.0 h1:W5hyXNComRa23tGpKwG+FRAc4rfF6ZUg1JReK+QHS80= +go.opentelemetry.io/proto/otlp v0.18.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -243,6 +298,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -264,8 +320,10 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -274,8 +332,11 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -305,22 +366,47 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= -golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220728030405-41545e8bf201 h1:bvOltf3SADAfG05iRml8lAB3qjoEX5RCyN4K6G5v3N0= +golang.org/x/net v0.0.0-20220728030405-41545e8bf201/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220718184931-c8730f7fcb92/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -330,7 +416,9 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -360,19 +448,47 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -380,6 +496,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= @@ -427,14 +544,28 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -451,12 +582,36 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -487,13 +642,58 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To= -google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8 h1:qRu95HZ148xXw+XeZ3dvqe85PxH4X8+jIo0iRPKcEnM= -google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220719170305-83ca9fad585f/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b h1:SfSkJugek6xm7lWywqth4r2iTrYLpD8lOj1nMIIhMNM= +google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -506,15 +706,29 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -542,7 +756,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= @@ -557,4 +770,3 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/example/redis-bloom/go.mod b/example/redis-bloom/go.mod index 7d25def773..409b38a5c8 100644 --- a/example/redis-bloom/go.mod +++ b/example/redis-bloom/go.mod @@ -4,4 +4,4 @@ go 1.14 replace github.com/go-redis/redis/v9 => ../.. -require github.com/go-redis/redis/v9 v9.0.0-beta.1 +require github.com/go-redis/redis/v9 v9.0.0-beta.2 diff --git a/example/redis-bloom/go.sum b/example/redis-bloom/go.sum index f694e5247c..224bfa9034 100644 --- a/example/redis-bloom/go.sum +++ b/example/redis-bloom/go.sum @@ -24,8 +24,9 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -37,32 +38,41 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -76,8 +86,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -88,10 +101,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -100,8 +113,9 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -110,5 +124,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/example/scan-struct/go.mod b/example/scan-struct/go.mod index 761414a490..116734ec54 100644 --- a/example/scan-struct/go.mod +++ b/example/scan-struct/go.mod @@ -6,5 +6,5 @@ replace github.com/go-redis/redis/v9 => ../.. require ( github.com/davecgh/go-spew v1.1.1 - github.com/go-redis/redis/v9 v9.0.0-beta.1 + github.com/go-redis/redis/v9 v9.0.0-beta.2 ) diff --git a/example/scan-struct/go.sum b/example/scan-struct/go.sum index e14c74224a..80595db60d 100644 --- a/example/scan-struct/go.sum +++ b/example/scan-struct/go.sum @@ -25,8 +25,9 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -38,32 +39,41 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -77,8 +87,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -89,10 +102,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -101,8 +114,9 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -111,5 +125,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/extra/rediscensus/go.mod b/extra/rediscensus/go.mod index bc58127b11..0bea27f360 100644 --- a/extra/rediscensus/go.mod +++ b/extra/rediscensus/go.mod @@ -7,8 +7,8 @@ replace github.com/go-redis/redis/v9 => ../.. replace github.com/go-redis/redis/extra/rediscmd/v9 => ../rediscmd require ( - github.com/go-redis/redis/extra/rediscmd/v9 v9.0.0-beta.1 - github.com/go-redis/redis/v9 v9.0.0-beta.1 + github.com/go-redis/redis/extra/rediscmd/v9 v9.0.0-beta.2 + github.com/go-redis/redis/v9 v9.0.0-beta.2 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect go.opencensus.io v0.23.0 ) diff --git a/extra/rediscensus/go.sum b/extra/rediscensus/go.sum index 2cc377b3a2..3ed9388dea 100644 --- a/extra/rediscensus/go.sum +++ b/extra/rediscensus/go.sum @@ -44,8 +44,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -58,29 +59,34 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -91,14 +97,18 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -113,8 +123,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -129,10 +142,10 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -154,8 +167,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -164,8 +178,9 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/extra/rediscmd/go.mod b/extra/rediscmd/go.mod index 48b73744f2..944c496883 100644 --- a/extra/rediscmd/go.mod +++ b/extra/rediscmd/go.mod @@ -5,7 +5,7 @@ go 1.15 replace github.com/go-redis/redis/v9 => ../.. require ( - github.com/go-redis/redis/v9 v9.0.0-beta.1 + github.com/go-redis/redis/v9 v9.0.0-beta.2 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.19.0 + github.com/onsi/gomega v1.20.0 ) diff --git a/extra/rediscmd/go.sum b/extra/rediscmd/go.sum index f694e5247c..224bfa9034 100644 --- a/extra/rediscmd/go.sum +++ b/extra/rediscmd/go.sum @@ -24,8 +24,9 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -37,32 +38,41 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -76,8 +86,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -88,10 +101,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -100,8 +113,9 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -110,5 +124,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod index 96d48ee66f..4677366b97 100644 --- a/extra/redisotel/go.mod +++ b/extra/redisotel/go.mod @@ -7,9 +7,9 @@ replace github.com/go-redis/redis/v9 => ../.. replace github.com/go-redis/redis/extra/rediscmd/v9 => ../rediscmd require ( - github.com/go-redis/redis/extra/rediscmd/v9 v9.0.0-beta.1 - github.com/go-redis/redis/v9 v9.0.0-beta.1 - go.opentelemetry.io/otel v1.7.0 + github.com/go-redis/redis/extra/rediscmd/v9 v9.0.0-beta.2 + github.com/go-redis/redis/v9 v9.0.0-beta.2 + go.opentelemetry.io/otel v1.8.0 go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.7.0 + go.opentelemetry.io/otel/trace v1.8.0 ) diff --git a/extra/redisotel/go.sum b/extra/redisotel/go.sum index 6521762e47..3e6357a7dd 100644 --- a/extra/redisotel/go.sum +++ b/extra/redisotel/go.sum @@ -31,8 +31,9 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -44,13 +45,15 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -59,29 +62,36 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4= -go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= -go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= +go.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg= +go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= go.opentelemetry.io/otel/sdk v1.4.1 h1:J7EaW71E0v87qflB4cDolaqq3AcujGrtyIPGQoZOB0Y= go.opentelemetry.io/otel/sdk v1.4.1/go.mod h1:NBwHDgDIBYjwK2WNu1OPgsIc2IJzmBXNnvIJxJc8BpE= go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc= -go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= -go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= +go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY= +go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -96,8 +106,11 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -108,10 +121,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -120,8 +133,9 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -130,7 +144,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/package.json b/package.json index 8ff0ef68d2..7a25d76b0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redis", - "version": "9.0.0-beta.1", + "version": "9.0.0-beta.2", "main": "index.js", "repository": "git@github.com:go-redis/redis.git", "author": "Vladimir Mihailenco ", diff --git a/version.go b/version.go index e08b7407d2..194a8314cc 100644 --- a/version.go +++ b/version.go @@ -2,5 +2,5 @@ package redis // Version is the current release version. func Version() string { - return "9.0.0-beta.1" + return "9.0.0-beta.2" } From 2aeddfaa28c6b35eb568e81a561125666b16039a Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Fri, 29 Jul 2022 14:28:22 +0300 Subject: [PATCH 061/621] fix: fix ClusterSlots to read full metadata --- command.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/command.go b/command.go index a6f74dbe84..319bfba25c 100644 --- a/command.go +++ b/command.go @@ -2822,19 +2822,14 @@ func (cmd *ClusterSlotsCmd) readReply(rd *proto.Reader) error { } if nn >= 4 { - networkingMetadata := make(map[string]string) - metadataLength, err := rd.ReadMapLen() if err != nil { return err } - if metadataLength%2 != 0 { - return fmt.Errorf( - "got %d elements in metadata, expected an even number", metadataLength) - } + networkingMetadata := make(map[string]string, metadataLength) - for i := 0; i < metadataLength; i += 2 { + for i := 0; i < metadataLength; i++ { key, err := rd.ReadString() if err != nil { return err From b50b1c8f7aaccc257dca477209d74d4cd2cbef80 Mon Sep 17 00:00:00 2001 From: jianghang Date: Tue, 2 Aug 2022 00:05:40 +0800 Subject: [PATCH 062/621] chore(internal): remove duplicate safe & unsafe --- command.go | 2 +- internal/arg.go | 4 +++- internal/safe.go | 12 ------------ internal/unsafe.go | 21 --------------------- 4 files changed, 4 insertions(+), 35 deletions(-) delete mode 100644 internal/safe.go delete mode 100644 internal/unsafe.go diff --git a/command.go b/command.go index 319bfba25c..cb1f26a31d 100644 --- a/command.go +++ b/command.go @@ -104,7 +104,7 @@ func cmdString(cmd Cmder, val interface{}) string { b = internal.AppendArg(b, val) } - return internal.String(b) + return util.BytesToString(b) } //------------------------------------------------------------------------------ diff --git a/internal/arg.go b/internal/arg.go index b97fa0d685..af5f8c9382 100644 --- a/internal/arg.go +++ b/internal/arg.go @@ -4,6 +4,8 @@ import ( "fmt" "strconv" "time" + + "github.com/go-redis/redis/v9/internal/util" ) func AppendArg(b []byte, v interface{}) []byte { @@ -11,7 +13,7 @@ func AppendArg(b []byte, v interface{}) []byte { case nil: return append(b, ""...) case string: - return appendUTF8String(b, Bytes(v)) + return appendUTF8String(b, util.StringToBytes(v)) case []byte: return appendUTF8String(b, v) case int: diff --git a/internal/safe.go b/internal/safe.go deleted file mode 100644 index fd2f434094..0000000000 --- a/internal/safe.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build appengine -// +build appengine - -package internal - -func String(b []byte) string { - return string(b) -} - -func Bytes(s string) []byte { - return []byte(s) -} diff --git a/internal/unsafe.go b/internal/unsafe.go deleted file mode 100644 index 9f2e418f79..0000000000 --- a/internal/unsafe.go +++ /dev/null @@ -1,21 +0,0 @@ -//go:build !appengine -// +build !appengine - -package internal - -import "unsafe" - -// String converts byte slice to string. -func String(b []byte) string { - return *(*string)(unsafe.Pointer(&b)) -} - -// Bytes converts string to byte slice. -func Bytes(s string) []byte { - return *(*[]byte)(unsafe.Pointer( - &struct { - string - Cap int - }{s, len(s)}, - )) -} From 6f7f800107ba67310cd822d35b4558255f702ff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandor=20Sz=C3=BCcs?= Date: Mon, 23 May 2022 22:14:49 +0200 Subject: [PATCH 063/621] feat: ring.SetAddrs to add and remove shards by the ring client and reuse old connections test: ring scale-in and scale-out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rewrite as suggested by @AlexanderYastrebov Signed-off-by: Sandor Szücs --- export_test.go | 8 +++++ ring.go | 88 ++++++++++++++++++++++++++++++++++++++++++-------- ring_test.go | 73 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 14 deletions(-) diff --git a/export_test.go b/export_test.go index 5e6d746681..cae7faa3d9 100644 --- a/export_test.go +++ b/export_test.go @@ -93,3 +93,11 @@ func GetSlavesAddrByName(ctx context.Context, c *SentinelClient, name string) [] } return parseReplicaAddrs(addrs, false) } + +func (c *Ring) GetAddr(addr string) *ringShard { + return c.shards.GetAddr(addr) +} + +func (c *ringShards) GetAddr(addr string) *ringShard { + return c.shards[addr] +} diff --git a/ring.go b/ring.go index dede1e4959..65c7ce89ee 100644 --- a/ring.go +++ b/ring.go @@ -160,6 +160,7 @@ func (opt *RingOptions) clientOptions() *Options { type ringShard struct { Client *Client down int32 + addr string } func newRingShard(opt *RingOptions, name, addr string) *ringShard { @@ -168,6 +169,7 @@ func newRingShard(opt *RingOptions, name, addr string) *ringShard { return &ringShard{ Client: opt.NewClient(name, clopt), + addr: addr, } } @@ -212,33 +214,68 @@ type ringShards struct { opt *RingOptions mu sync.RWMutex + muClose sync.Mutex hash ConsistentHash - shards map[string]*ringShard // read only - list []*ringShard // read only + shards map[string]*ringShard // read only, updated by SetAddrs + list []*ringShard // read only, updated by SetAddrs numShard int closed bool } func newRingShards(opt *RingOptions) *ringShards { - shards := make(map[string]*ringShard, len(opt.Addrs)) - list := make([]*ringShard, 0, len(shards)) + c := &ringShards{ + opt: opt, + } + c.SetAddrs(opt.Addrs) - for name, addr := range opt.Addrs { - shard := newRingShard(opt, name, addr) - shards[name] = shard + return c +} - list = append(list, shard) +// SetAddrs replaces the shards in use, such that you can increase and +// decrease number of shards, that you use. It will reuse shards that +// existed before and close the ones that will not be used anymore. +func (c *ringShards) SetAddrs(addrs map[string]string) { + c.muClose.Lock() + defer c.muClose.Unlock() + if c.closed { + return } - c := &ringShards{ - opt: opt, + shards := make(map[string]*ringShard) + unusedShards := make(map[string]*ringShard) + + for k, shard := range c.shards { + if addr, ok := addrs[k]; ok && shard.addr == addr { + shards[k] = shard + } else { + unusedShards[k] = shard + } + } - shards: shards, - list: list, + for k, addr := range addrs { + if shard, ok := c.shards[k]; !ok || shard.addr != addr { + shards[k] = newRingShard(c.opt, k, addr) + } } - c.rebalance() - return c + list := make([]*ringShard, 0, len(shards)) + for _, shard := range shards { + list = append(list, shard) + } + + c.mu.Lock() + c.shards = shards + c.list = list + + c.rebalanceLocked() + c.mu.Unlock() + + for k, shard := range unusedShards { + err := shard.Client.Close() + if err != nil { + internal.Logger.Printf(context.Background(), "Failed to close ring shard client %s %s: %v", k, shard.addr, err) + } + } } func (c *ringShards) List() []*ringShard { @@ -355,6 +392,23 @@ func (c *ringShards) rebalance() { c.mu.Unlock() } +// rebalanceLocked removes dead shards from the Ring and callers need to hold the locl +func (c *ringShards) rebalanceLocked() { + shards := c.shards + liveShards := make([]string, 0, len(shards)) + + for name, shard := range shards { + if shard.IsUp() { + liveShards = append(liveShards, name) + } + } + + hash := c.opt.NewConsistentHash(liveShards) + + c.hash = hash + c.numShard = len(liveShards) +} + func (c *ringShards) Len() int { c.mu.RLock() defer c.mu.RUnlock() @@ -363,6 +417,8 @@ func (c *ringShards) Len() int { } func (c *ringShards) Close() error { + c.muClose.Lock() + defer c.muClose.Unlock() c.mu.Lock() defer c.mu.Unlock() @@ -436,6 +492,10 @@ func NewRing(opt *RingOptions) *Ring { return &ring } +func (c *Ring) SetAddrs(ctx context.Context, addrs map[string]string) { + c.shards.SetAddrs(addrs) +} + // Do creates a Cmd from the args and processes the cmd. func (c *Ring) Do(ctx context.Context, args ...interface{}) *Cmd { cmd := NewCmd(ctx, args...) diff --git a/ring_test.go b/ring_test.go index 1a6ec84b99..d80406282c 100644 --- a/ring_test.go +++ b/ring_test.go @@ -113,6 +113,79 @@ var _ = Describe("Redis Ring", func() { Expect(ringShard2.Info(ctx, "keyspace").Val()).To(ContainSubstring("keys=100")) }) + Describe("[new] dynamic setting ring shards", func() { + It("downscale shard and check reuse shard, upscale shard and check reuse", func() { + Expect(ring.Len(), 2) + + wantShard := ring.GetAddr("ringShardOne") + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + ring.SetAddrs(ctx, map[string]string{ + "ringShardOne": ":" + ringShard1Port, + }) + Expect(ring.Len(), 1) + gotShard := ring.GetAddr("ringShardOne") + Expect(gotShard).To(Equal(wantShard)) + + ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + ring.SetAddrs(ctx, map[string]string{ + "ringShardOne": ":" + ringShard1Port, + "ringShardTwo": ":" + ringShard2Port, + }) + Expect(ring.Len(), 2) + gotShard = ring.GetAddr("ringShardOne") + Expect(gotShard).To(Equal(wantShard)) + + }) + + It("uses 3 shards after setting it to 3 shards", func() { + Expect(ring.Len(), 2) + + // Start ringShard3. + var err error + ringShard3, err = startRedis(ringShard3Port) + Expect(err).NotTo(HaveOccurred()) + + shardName1 := "ringShardOne" + shardAddr1 := ":" + ringShard1Port + wantShard1 := ring.GetAddr(shardName1) + shardName2 := "ringShardTwo" + shardAddr2 := ":" + ringShard2Port + wantShard2 := ring.GetAddr(shardName2) + shardName3 := "ringShardThree" + shardAddr3 := ":" + ringShard3Port + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + ring.SetAddrs(ctx, map[string]string{ + shardName1: shardAddr1, + shardName2: shardAddr2, + shardName3: shardAddr3, + }) + Expect(ring.Len(), 3) + gotShard1 := ring.GetAddr(shardName1) + gotShard2 := ring.GetAddr(shardName2) + gotShard3 := ring.GetAddr(shardName3) + Expect(gotShard1).To(Equal(wantShard1)) + Expect(gotShard2).To(Equal(wantShard2)) + Expect(gotShard3).ToNot(BeNil()) + + ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + ring.SetAddrs(ctx, map[string]string{ + shardName1: shardAddr1, + shardName2: shardAddr2, + }) + Expect(ring.Len(), 2) + gotShard1 = ring.GetAddr(shardName1) + gotShard2 = ring.GetAddr(shardName2) + gotShard3 = ring.GetAddr(shardName3) + Expect(gotShard1).To(Equal(wantShard1)) + Expect(gotShard2).To(Equal(wantShard2)) + Expect(gotShard3).To(BeNil()) + }) + + }) Describe("pipeline", func() { It("doesn't panic closed ring, returns error", func() { pipe := ring.Pipeline() From baa48a4415f7760ed80275acfe0747dd13342937 Mon Sep 17 00:00:00 2001 From: jianghang Date: Wed, 3 Aug 2022 23:10:03 +0800 Subject: [PATCH 064/621] feat(pubsub): support sharded pub/sub --- cluster.go | 10 +++++ cluster_test.go | 24 +++++++++++ commands.go | 31 ++++++++++++++ pubsub.go | 41 ++++++++++++++++++- pubsub_test.go | 105 ++++++++++++++++++++++++++++++++++++++++++++++++ redis.go | 10 +++++ ring.go | 13 ++++++ universal.go | 1 + 8 files changed, 233 insertions(+), 2 deletions(-) diff --git a/cluster.go b/cluster.go index 05b234aacf..ea312284c4 100644 --- a/cluster.go +++ b/cluster.go @@ -1528,6 +1528,16 @@ func (c *ClusterClient) PSubscribe(ctx context.Context, channels ...string) *Pub return pubsub } +// SSubscribe Subscribes the client to the specified shard channels. +func (c *ClusterClient) SSubscribe(ctx context.Context, channels ...string) *PubSub { + pubsub := c.pubSub() + if len(channels) > 0 { + _ = pubsub.SSubscribe(ctx, channels...) + } + return pubsub +} + + func (c *ClusterClient) retryBackoff(attempt int) time.Duration { return internal.RetryBackoff(attempt, c.opt.MinRetryBackoff, c.opt.MaxRetryBackoff) } diff --git a/cluster_test.go b/cluster_test.go index ee37dc2dba..e503ea84ff 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -549,6 +549,30 @@ var _ = Describe("ClusterClient", func() { }, 30*time.Second).ShouldNot(HaveOccurred()) }) + It("supports sharded PubSub", func() { + pubsub := client.SSubscribe(ctx, "mychannel") + defer pubsub.Close() + + Eventually(func() error { + _, err := client.SPublish(ctx, "mychannel", "hello").Result() + if err != nil { + return err + } + + msg, err := pubsub.ReceiveTimeout(ctx, time.Second) + if err != nil { + return err + } + + _, ok := msg.(*redis.Message) + if !ok { + return fmt.Errorf("got %T, wanted *redis.Message", msg) + } + + return nil + }, 30*time.Second).ShouldNot(HaveOccurred()) + }) + It("supports PubSub.Ping without channels", func() { pubsub := client.Subscribe(ctx) defer pubsub.Close() diff --git a/commands.go b/commands.go index beb3af2d16..8db115d304 100644 --- a/commands.go +++ b/commands.go @@ -345,9 +345,12 @@ type Cmdable interface { ScriptLoad(ctx context.Context, script string) *StringCmd Publish(ctx context.Context, channel string, message interface{}) *IntCmd + SPublish(ctx context.Context, channel string, message interface{}) *IntCmd PubSubChannels(ctx context.Context, pattern string) *StringSliceCmd PubSubNumSub(ctx context.Context, channels ...string) *StringIntMapCmd PubSubNumPat(ctx context.Context) *IntCmd + PubSubShardChannels(ctx context.Context, pattern string) *StringSliceCmd + PubSubShardNumSub(ctx context.Context, channels ...string) *StringIntMapCmd ClusterSlots(ctx context.Context) *ClusterSlotsCmd ClusterNodes(ctx context.Context) *StringCmd @@ -3078,6 +3081,12 @@ func (c cmdable) Publish(ctx context.Context, channel string, message interface{ return cmd } +func (c cmdable) SPublish(ctx context.Context, channel string, message interface{}) *IntCmd { + cmd := NewIntCmd(ctx, "spublish", channel, message) + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) PubSubChannels(ctx context.Context, pattern string) *StringSliceCmd { args := []interface{}{"pubsub", "channels"} if pattern != "*" { @@ -3100,6 +3109,28 @@ func (c cmdable) PubSubNumSub(ctx context.Context, channels ...string) *StringIn return cmd } +func (c cmdable) PubSubShardChannels(ctx context.Context, pattern string) *StringSliceCmd { + args := []interface{}{"pubsub", "shardchannels"} + if pattern != "*" { + args = append(args, pattern) + } + cmd := NewStringSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) PubSubShardNumSub(ctx context.Context, channels ...string) *StringIntMapCmd { + args := make([]interface{}, 2+len(channels)) + args[0] = "pubsub" + args[1] = "shardnumsub" + for i, channel := range channels { + args[2+i] = channel + } + cmd := NewStringIntMapCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) PubSubNumPat(ctx context.Context) *IntCmd { cmd := NewIntCmd(ctx, "pubsub", "numpat") _ = c(ctx, cmd) diff --git a/pubsub.go b/pubsub.go index 75e5097b0b..6eede91808 100644 --- a/pubsub.go +++ b/pubsub.go @@ -28,6 +28,7 @@ type PubSub struct { cn *pool.Conn channels map[string]struct{} patterns map[string]struct{} + schannels map[string]struct{} closed bool exit chan struct{} @@ -46,6 +47,7 @@ func (c *PubSub) init() { func (c *PubSub) String() string { channels := mapKeys(c.channels) channels = append(channels, mapKeys(c.patterns)...) + channels = append(channels, mapKeys(c.schannels)...) return fmt.Sprintf("PubSub(%s)", strings.Join(channels, ", ")) } @@ -101,6 +103,13 @@ func (c *PubSub) resubscribe(ctx context.Context, cn *pool.Conn) error { } } + if len(c.schannels) > 0 { + err := c._subscribe(ctx, cn, "ssubscribe", mapKeys(c.schannels)) + if err != nil && firstErr == nil { + firstErr = err + } + } + return firstErr } @@ -208,6 +217,21 @@ func (c *PubSub) PSubscribe(ctx context.Context, patterns ...string) error { return err } +// SSubscribe Subscribes the client to the specified shard channels. +func (c *PubSub) SSubscribe(ctx context.Context, channels ...string) error { + c.mu.Lock() + defer c.mu.Unlock() + + err := c.subscribe(ctx, "ssubscribe", channels...) + if c.schannels == nil { + c.schannels = make(map[string]struct{}) + } + for _, s := range channels { + c.schannels[s] = struct{}{} + } + return err +} + // Unsubscribe the client from the given channels, or from all of // them if none is given. func (c *PubSub) Unsubscribe(ctx context.Context, channels ...string) error { @@ -234,6 +258,19 @@ func (c *PubSub) PUnsubscribe(ctx context.Context, patterns ...string) error { return err } +// SUnsubscribe unsubscribes the client from the given shard channels, +// or from all of them if none is given. +func (c *PubSub) SUnsubscribe(ctx context.Context, channels ...string) error { + c.mu.Lock() + defer c.mu.Unlock() + + for _, channel := range channels { + delete(c.schannels, channel) + } + err := c.subscribe(ctx, "sunsubscribe", channels...) + return err +} + func (c *PubSub) subscribe(ctx context.Context, redisCmd string, channels ...string) error { cn, err := c.conn(ctx, channels) if err != nil { @@ -311,7 +348,7 @@ func (c *PubSub) newMessage(reply interface{}) (interface{}, error) { }, nil case []interface{}: switch kind := reply[0].(string); kind { - case "subscribe", "unsubscribe", "psubscribe", "punsubscribe": + case "subscribe", "unsubscribe", "psubscribe", "punsubscribe", "ssubscribe", "sunsubscribe": // Can be nil in case of "unsubscribe". channel, _ := reply[1].(string) return &Subscription{ @@ -319,7 +356,7 @@ func (c *PubSub) newMessage(reply interface{}) (interface{}, error) { Channel: channel, Count: int(reply[2].(int64)), }, nil - case "message": + case "message", "smessage": switch payload := reply[2].(type) { case string: return &Message{ diff --git a/pubsub_test.go b/pubsub_test.go index 892118e02c..37f0e9934a 100644 --- a/pubsub_test.go +++ b/pubsub_test.go @@ -102,6 +102,35 @@ var _ = Describe("PubSub", func() { Expect(len(channels)).To(BeNumerically(">=", 2)) }) + It("should sharded pub/sub channels", func() { + channels, err := client.PubSubShardChannels(ctx, "mychannel*").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(channels).To(BeEmpty()) + + pubsub := client.SSubscribe(ctx, "mychannel", "mychannel2") + defer pubsub.Close() + + channels, err = client.PubSubShardChannels(ctx, "mychannel*").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(channels).To(ConsistOf([]string{"mychannel", "mychannel2"})) + + channels, err = client.PubSubShardChannels(ctx, "").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(channels).To(BeEmpty()) + + channels, err = client.PubSubShardChannels(ctx, "*").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(len(channels)).To(BeNumerically(">=", 2)) + + nums, err := client.PubSubShardNumSub(ctx, "mychannel", "mychannel2", "mychannel3").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(nums).To(Equal(map[string]int64{ + "mychannel": 1, + "mychannel2": 1, + "mychannel3": 0, + })) + }) + It("should return the numbers of subscribers", func() { pubsub := client.Subscribe(ctx, "mychannel", "mychannel2") defer pubsub.Close() @@ -204,6 +233,82 @@ var _ = Describe("PubSub", func() { Expect(stats.Misses).To(Equal(uint32(1))) }) + It("should sharded pub/sub", func() { + pubsub := client.SSubscribe(ctx, "mychannel", "mychannel2") + defer pubsub.Close() + + { + msgi, err := pubsub.ReceiveTimeout(ctx, time.Second) + Expect(err).NotTo(HaveOccurred()) + subscr := msgi.(*redis.Subscription) + Expect(subscr.Kind).To(Equal("ssubscribe")) + Expect(subscr.Channel).To(Equal("mychannel")) + Expect(subscr.Count).To(Equal(1)) + } + + { + msgi, err := pubsub.ReceiveTimeout(ctx, time.Second) + Expect(err).NotTo(HaveOccurred()) + subscr := msgi.(*redis.Subscription) + Expect(subscr.Kind).To(Equal("ssubscribe")) + Expect(subscr.Channel).To(Equal("mychannel2")) + Expect(subscr.Count).To(Equal(2)) + } + + { + msgi, err := pubsub.ReceiveTimeout(ctx, time.Second) + Expect(err.(net.Error).Timeout()).To(Equal(true)) + Expect(msgi).NotTo(HaveOccurred()) + } + + n, err := client.SPublish(ctx, "mychannel", "hello").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(n).To(Equal(int64(1))) + + n, err = client.SPublish(ctx, "mychannel2", "hello2").Result() + Expect(err).NotTo(HaveOccurred()) + Expect(n).To(Equal(int64(1))) + + Expect(pubsub.SUnsubscribe(ctx, "mychannel", "mychannel2")).NotTo(HaveOccurred()) + + { + msgi, err := pubsub.ReceiveTimeout(ctx, time.Second) + Expect(err).NotTo(HaveOccurred()) + msg := msgi.(*redis.Message) + Expect(msg.Channel).To(Equal("mychannel")) + Expect(msg.Payload).To(Equal("hello")) + } + + { + msgi, err := pubsub.ReceiveTimeout(ctx, time.Second) + Expect(err).NotTo(HaveOccurred()) + msg := msgi.(*redis.Message) + Expect(msg.Channel).To(Equal("mychannel2")) + Expect(msg.Payload).To(Equal("hello2")) + } + + { + msgi, err := pubsub.ReceiveTimeout(ctx, time.Second) + Expect(err).NotTo(HaveOccurred()) + subscr := msgi.(*redis.Subscription) + Expect(subscr.Kind).To(Equal("sunsubscribe")) + Expect(subscr.Channel).To(Equal("mychannel")) + Expect(subscr.Count).To(Equal(1)) + } + + { + msgi, err := pubsub.ReceiveTimeout(ctx, time.Second) + Expect(err).NotTo(HaveOccurred()) + subscr := msgi.(*redis.Subscription) + Expect(subscr.Kind).To(Equal("sunsubscribe")) + Expect(subscr.Channel).To(Equal("mychannel2")) + Expect(subscr.Count).To(Equal(0)) + } + + stats := client.PoolStats() + Expect(stats.Misses).To(Equal(uint32(1))) + }) + It("should ping/pong", func() { pubsub := client.Subscribe(ctx, "mychannel") defer pubsub.Close() diff --git a/redis.go b/redis.go index f558181240..324a1ca839 100644 --- a/redis.go +++ b/redis.go @@ -691,6 +691,16 @@ func (c *Client) PSubscribe(ctx context.Context, channels ...string) *PubSub { return pubsub } +// SSubscribe Subscribes the client to the specified shard channels. +// Channels can be omitted to create empty subscription. +func (c *Client) SSubscribe(ctx context.Context, channels ...string) *PubSub { + pubsub := c.pubSub() + if len(channels) > 0 { + _ = pubsub.SSubscribe(ctx, channels...) + } + return pubsub +} + //------------------------------------------------------------------------------ type conn struct { diff --git a/ring.go b/ring.go index dede1e4959..9386dfe463 100644 --- a/ring.go +++ b/ring.go @@ -504,6 +504,19 @@ func (c *Ring) PSubscribe(ctx context.Context, channels ...string) *PubSub { return shard.Client.PSubscribe(ctx, channels...) } +// SSubscribe Subscribes the client to the specified shard channels. +func (c *Ring) SSubscribe(ctx context.Context, channels ...string) *PubSub { + if len(channels) == 0 { + panic("at least one channel is required") + } + shard, err := c.shards.GetByKey(channels[0]) + if err != nil { + // TODO: return PubSub with sticky error + panic(err) + } + return shard.Client.SSubscribe(ctx, channels...) +} + // ForEachShard concurrently calls the fn on each live shard in the ring. // It returns the first error if any. func (c *Ring) ForEachShard( diff --git a/universal.go b/universal.go index a3c5b9d0a1..f800935c38 100644 --- a/universal.go +++ b/universal.go @@ -190,6 +190,7 @@ type UniversalClient interface { Process(ctx context.Context, cmd Cmder) error Subscribe(ctx context.Context, channels ...string) *PubSub PSubscribe(ctx context.Context, channels ...string) *PubSub + SSubscribe(ctx context.Context, channels ...string) *PubSub Close() error PoolStats() *PoolStats } From 2123e084376cfc93be6e28d6308a008f97d2fd16 Mon Sep 17 00:00:00 2001 From: jianghang Date: Wed, 3 Aug 2022 22:43:37 +0800 Subject: [PATCH 065/621] fix(internal/pool): call SetDeadline even if timeout is zero --- internal/pool/conn.go | 12 ++++-------- options.go | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/internal/pool/conn.go b/internal/pool/conn.go index a760be2798..5b5079a585 100644 --- a/internal/pool/conn.go +++ b/internal/pool/conn.go @@ -64,10 +64,8 @@ func (cn *Conn) RemoteAddr() net.Addr { } func (cn *Conn) WithReader(ctx context.Context, timeout time.Duration, fn func(rd *proto.Reader) error) error { - if timeout != 0 { - if err := cn.netConn.SetReadDeadline(cn.deadline(ctx, timeout)); err != nil { - return err - } + if err := cn.netConn.SetReadDeadline(cn.deadline(ctx, timeout)); err != nil { + return err } return fn(cn.rd) } @@ -75,10 +73,8 @@ func (cn *Conn) WithReader(ctx context.Context, timeout time.Duration, fn func(r func (cn *Conn) WithWriter( ctx context.Context, timeout time.Duration, fn func(wr *proto.Writer) error, ) error { - if timeout != 0 { - if err := cn.netConn.SetWriteDeadline(cn.deadline(ctx, timeout)); err != nil { - return err - } + if err := cn.netConn.SetWriteDeadline(cn.deadline(ctx, timeout)); err != nil { + return err } if cn.bw.Buffered() > 0 { diff --git a/options.go b/options.go index 8f5f380fc9..0c2cb1d1f8 100644 --- a/options.go +++ b/options.go @@ -76,7 +76,7 @@ type Options struct { // Default is 3 seconds. ReadTimeout time.Duration // Timeout for socket writes. If reached, commands will fail - // with a timeout instead of blocking. + // with a timeout instead of blocking. Use value -1 for no timeout and 0 for default. // Default is ReadTimeout. WriteTimeout time.Duration From 3f8edc686f42be62cdc0630fca788c16e475efd1 Mon Sep 17 00:00:00 2001 From: Adam Snyder Date: Sun, 7 Aug 2022 21:06:04 -0700 Subject: [PATCH 066/621] feat: add some missing SetVal methods --- command.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/command.go b/command.go index cb1f26a31d..2586ea7d00 100644 --- a/command.go +++ b/command.go @@ -1093,6 +1093,10 @@ func NewKeyValueSliceCmd(ctx context.Context, args ...interface{}) *KeyValueSlic } } +func (cmd *KeyValueSliceCmd) SetVal(val []KeyValue) { + cmd.val = val +} + func (cmd *KeyValueSliceCmd) Val() []KeyValue { return cmd.val } @@ -3117,6 +3121,10 @@ func NewGeoSearchLocationCmd( } } +func (cmd *GeoSearchLocationCmd) SetVal(val []GeoLocation) { + cmd.val = val +} + func (cmd *GeoSearchLocationCmd) Val() []GeoLocation { return cmd.val } @@ -3573,6 +3581,10 @@ func NewMapStringInterfaceCmd(ctx context.Context, args ...interface{}) *MapStri } } +func (cmd *MapStringInterfaceCmd) SetVal(val map[string]interface{}) { + cmd.val = val +} + func (cmd *MapStringInterfaceCmd) Val() map[string]interface{} { return cmd.val } @@ -3633,6 +3645,10 @@ func NewMapStringStringSliceCmd(ctx context.Context, args ...interface{}) *MapSt } } +func (cmd *MapStringStringSliceCmd) SetVal(val []map[string]string) { + cmd.val = val +} + func (cmd *MapStringStringSliceCmd) Val() []map[string]string { return cmd.val } From faa496ba7de1540361968346a0a25e7fc3cbeec3 Mon Sep 17 00:00:00 2001 From: Adam Snyder Date: Sun, 7 Aug 2022 22:40:51 -0700 Subject: [PATCH 067/621] test: vet that all Cmders have a SetVal() method --- Makefile | 2 + internal/customvet/.gitignore | 1 + internal/customvet/checks/setval/setval.go | 61 +++++++++++++++++++ .../customvet/checks/setval/setval_test.go | 12 ++++ .../checks/setval/testdata/src/a/a.go | 29 +++++++++ internal/customvet/go.mod | 10 +++ internal/customvet/go.sum | 26 ++++++++ internal/customvet/main.go | 12 ++++ 8 files changed, 153 insertions(+) create mode 100644 internal/customvet/.gitignore create mode 100644 internal/customvet/checks/setval/setval.go create mode 100644 internal/customvet/checks/setval/setval_test.go create mode 100644 internal/customvet/checks/setval/testdata/src/a/a.go create mode 100644 internal/customvet/go.mod create mode 100644 internal/customvet/go.sum create mode 100644 internal/customvet/main.go diff --git a/Makefile b/Makefile index 5dbd7ae837..6399210c32 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,8 @@ test: testdeps go test ./... -run=NONE -bench=. -benchmem env GOOS=linux GOARCH=386 go test ./... go vet + cd internal/customvet && go build . + go vet -vettool ./internal/customvet/customvet testdeps: testdata/redis/src/redis-server diff --git a/internal/customvet/.gitignore b/internal/customvet/.gitignore new file mode 100644 index 0000000000..6341ecb851 --- /dev/null +++ b/internal/customvet/.gitignore @@ -0,0 +1 @@ +/customvet diff --git a/internal/customvet/checks/setval/setval.go b/internal/customvet/checks/setval/setval.go new file mode 100644 index 0000000000..e629f5f7aa --- /dev/null +++ b/internal/customvet/checks/setval/setval.go @@ -0,0 +1,61 @@ +package setval + +import ( + "go/ast" + "go/token" + "go/types" + "golang.org/x/tools/go/analysis" +) + +var Analyzer = &analysis.Analyzer{ + Name: "setval", + Doc: "find Cmder types that are missing a SetVal method", + + Run: func(pass *analysis.Pass) (interface{}, error) { + cmderTypes := make(map[string]token.Pos) + typesWithSetValMethod := make(map[string]bool) + + for _, file := range pass.Files { + for _, decl := range file.Decls { + funcName, receiverType := parseFuncDecl(decl, pass.TypesInfo) + + switch funcName { + case "Result": + cmderTypes[receiverType] = decl.Pos() + case "SetVal": + typesWithSetValMethod[receiverType] = true + } + } + } + + for cmder, pos := range cmderTypes { + if !typesWithSetValMethod[cmder] { + pass.Reportf(pos, "%s is missing a SetVal method", cmder) + } + } + + return nil, nil + }, +} + +func parseFuncDecl(decl ast.Decl, typesInfo *types.Info) (funcName, receiverType string) { + funcDecl, ok := decl.(*ast.FuncDecl) + if !ok { + return "", "" // Not a function declaration. + } + + if funcDecl.Recv == nil { + return "", "" // Not a method. + } + + if len(funcDecl.Recv.List) != 1 { + return "", "" // Unexpected number of receiver arguments. (Can this happen?) + } + + receiverTypeObj := typesInfo.TypeOf(funcDecl.Recv.List[0].Type) + if receiverTypeObj == nil { + return "", "" // Unable to determine the receiver type. + } + + return funcDecl.Name.Name, receiverTypeObj.String() +} diff --git a/internal/customvet/checks/setval/setval_test.go b/internal/customvet/checks/setval/setval_test.go new file mode 100644 index 0000000000..44377439ae --- /dev/null +++ b/internal/customvet/checks/setval/setval_test.go @@ -0,0 +1,12 @@ +package setval_test + +import ( + "github.com/go-redis/redis/internal/customvet/checks/setval" + "golang.org/x/tools/go/analysis/analysistest" + "testing" +) + +func Test(t *testing.T) { + testdata := analysistest.TestData() + analysistest.Run(t, testdata, setval.Analyzer, "a") +} diff --git a/internal/customvet/checks/setval/testdata/src/a/a.go b/internal/customvet/checks/setval/testdata/src/a/a.go new file mode 100644 index 0000000000..035cb5d34d --- /dev/null +++ b/internal/customvet/checks/setval/testdata/src/a/a.go @@ -0,0 +1,29 @@ +package a + +type GoodCmd struct { + val int +} + +func (c *GoodCmd) SetVal(val int) { + c.val = val +} + +func (c *GoodCmd) Result() (int, error) { + return c.val, nil +} + +type BadCmd struct { + val int +} + +func (c *BadCmd) Result() (int, error) { // want "\\*a.BadCmd is missing a SetVal method" + return c.val, nil +} + +type NotACmd struct { + val int +} + +func (c *NotACmd) Val() int { + return c.val +} diff --git a/internal/customvet/go.mod b/internal/customvet/go.mod new file mode 100644 index 0000000000..d3bce547a9 --- /dev/null +++ b/internal/customvet/go.mod @@ -0,0 +1,10 @@ +module github.com/go-redis/redis/internal/customvet + +go 1.17 + +require golang.org/x/tools v0.1.12 + +require ( + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect +) diff --git a/internal/customvet/go.sum b/internal/customvet/go.sum new file mode 100644 index 0000000000..3ddae732dd --- /dev/null +++ b/internal/customvet/go.sum @@ -0,0 +1,26 @@ +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/customvet/main.go b/internal/customvet/main.go new file mode 100644 index 0000000000..a6146dcfbe --- /dev/null +++ b/internal/customvet/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/go-redis/redis/internal/customvet/checks/setval" + "golang.org/x/tools/go/analysis/multichecker" +) + +func main() { + multichecker.Main( + setval.Analyzer, + ) +} From 9be4a9e6d3954397db2369ba03bdc49d0bdfd12e Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Mon, 8 Aug 2022 10:28:46 +0300 Subject: [PATCH 068/621] chore: fix some command names --- command.go | 18 +++++++++--------- commands.go | 6 +++--- result.go | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/command.go b/command.go index 2586ea7d00..d4fc91de8e 100644 --- a/command.go +++ b/command.go @@ -1292,16 +1292,16 @@ func (cmd *MapStringStringCmd) readReply(rd *proto.Reader) error { //------------------------------------------------------------------------------ -type StringIntMapCmd struct { +type MapStringIntCmd struct { baseCmd val map[string]int64 } -var _ Cmder = (*StringIntMapCmd)(nil) +var _ Cmder = (*MapStringIntCmd)(nil) -func NewStringIntMapCmd(ctx context.Context, args ...interface{}) *StringIntMapCmd { - return &StringIntMapCmd{ +func NewMapStringIntCmd(ctx context.Context, args ...interface{}) *MapStringIntCmd { + return &MapStringIntCmd{ baseCmd: baseCmd{ ctx: ctx, args: args, @@ -1309,23 +1309,23 @@ func NewStringIntMapCmd(ctx context.Context, args ...interface{}) *StringIntMapC } } -func (cmd *StringIntMapCmd) SetVal(val map[string]int64) { +func (cmd *MapStringIntCmd) SetVal(val map[string]int64) { cmd.val = val } -func (cmd *StringIntMapCmd) Val() map[string]int64 { +func (cmd *MapStringIntCmd) Val() map[string]int64 { return cmd.val } -func (cmd *StringIntMapCmd) Result() (map[string]int64, error) { +func (cmd *MapStringIntCmd) Result() (map[string]int64, error) { return cmd.val, cmd.err } -func (cmd *StringIntMapCmd) String() string { +func (cmd *MapStringIntCmd) String() string { return cmdString(cmd, cmd.val) } -func (cmd *StringIntMapCmd) readReply(rd *proto.Reader) error { +func (cmd *MapStringIntCmd) readReply(rd *proto.Reader) error { n, err := rd.ReadMapLen() if err != nil { return err diff --git a/commands.go b/commands.go index beb3af2d16..57de25b0ac 100644 --- a/commands.go +++ b/commands.go @@ -346,7 +346,7 @@ type Cmdable interface { Publish(ctx context.Context, channel string, message interface{}) *IntCmd PubSubChannels(ctx context.Context, pattern string) *StringSliceCmd - PubSubNumSub(ctx context.Context, channels ...string) *StringIntMapCmd + PubSubNumSub(ctx context.Context, channels ...string) *MapStringIntCmd PubSubNumPat(ctx context.Context) *IntCmd ClusterSlots(ctx context.Context) *ClusterSlotsCmd @@ -3088,14 +3088,14 @@ func (c cmdable) PubSubChannels(ctx context.Context, pattern string) *StringSlic return cmd } -func (c cmdable) PubSubNumSub(ctx context.Context, channels ...string) *StringIntMapCmd { +func (c cmdable) PubSubNumSub(ctx context.Context, channels ...string) *MapStringIntCmd { args := make([]interface{}, 2+len(channels)) args[0] = "pubsub" args[1] = "numsub" for i, channel := range channels { args[2+i] = channel } - cmd := NewStringIntMapCmd(ctx, args...) + cmd := NewMapStringIntCmd(ctx, args...) _ = c(ctx, cmd) return cmd } diff --git a/result.go b/result.go index 9401dfeebd..44741b01b5 100644 --- a/result.go +++ b/result.go @@ -83,16 +83,16 @@ func NewBoolSliceResult(val []bool, err error) *BoolSliceCmd { } // NewStringStringMapResult returns a StringStringMapCmd initialised with val and err for testing. -func NewStringStringMapResult(val map[string]string, err error) *MapStringStringCmd { +func NewMapStringStringResult(val map[string]string, err error) *MapStringStringCmd { var cmd MapStringStringCmd cmd.val = val cmd.SetErr(err) return &cmd } -// NewStringIntMapCmdResult returns a StringIntMapCmd initialised with val and err for testing. -func NewStringIntMapCmdResult(val map[string]int64, err error) *StringIntMapCmd { - var cmd StringIntMapCmd +// NewMapStringIntCmdResult returns a MapStringIntCmd initialised with val and err for testing. +func NewMapStringIntCmdResult(val map[string]int64, err error) *MapStringIntCmd { + var cmd MapStringIntCmd cmd.val = val cmd.SetErr(err) return &cmd From a10bc3e21cd9c10461d2e3476700babe6e3a3e0f Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Sat, 13 Aug 2022 11:05:04 +1000 Subject: [PATCH 069/621] fix: remove iterator mutex as it's not needed It's not safe to concurrently use an iterator even with a mutex. --- iterator.go | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/iterator.go b/iterator.go index 2f8bc2beda..cd1a828513 100644 --- a/iterator.go +++ b/iterator.go @@ -2,30 +2,21 @@ package redis import ( "context" - "sync" ) // ScanIterator is used to incrementally iterate over a collection of elements. -// It's safe for concurrent use by multiple goroutines. type ScanIterator struct { - mu sync.Mutex // protects Scanner and pos cmd *ScanCmd pos int } // Err returns the last iterator error, if any. func (it *ScanIterator) Err() error { - it.mu.Lock() - err := it.cmd.Err() - it.mu.Unlock() - return err + return it.cmd.Err() } // Next advances the cursor and returns true if more values can be read. func (it *ScanIterator) Next(ctx context.Context) bool { - it.mu.Lock() - defer it.mu.Unlock() - // Instantly return on errors. if it.cmd.Err() != nil { return false @@ -68,10 +59,8 @@ func (it *ScanIterator) Next(ctx context.Context) bool { // Val returns the key/field at the current cursor position. func (it *ScanIterator) Val() string { var v string - it.mu.Lock() if it.cmd.Err() == nil && it.pos > 0 && it.pos <= len(it.cmd.page) { v = it.cmd.page[it.pos-1] } - it.mu.Unlock() return v } From c6774f21fc1e66fa3b103ececf2ce9de201dc97e Mon Sep 17 00:00:00 2001 From: Aoang Date: Sun, 14 Aug 2022 16:26:49 +0800 Subject: [PATCH 070/621] chore: update CI Test Go version to v1.19 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0ae9434ed..ec300a92be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - go-version: [1.17.x, 1.18.x] + go-version: [1.18.x, 1.19.x] services: redis: From 59798f9dbae5081018b69c2ddf852b9da6d4833d Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Wed, 17 Aug 2022 13:18:58 +0300 Subject: [PATCH 071/621] chore: cleanup --- export_test.go | 8 +- ring.go | 210 ++++++++++++++++++++++++------------------------- ring_test.go | 34 ++++---- 3 files changed, 123 insertions(+), 129 deletions(-) diff --git a/export_test.go b/export_test.go index cae7faa3d9..f259fca0f5 100644 --- a/export_test.go +++ b/export_test.go @@ -94,10 +94,10 @@ func GetSlavesAddrByName(ctx context.Context, c *SentinelClient, name string) [] return parseReplicaAddrs(addrs, false) } -func (c *Ring) GetAddr(addr string) *ringShard { - return c.shards.GetAddr(addr) +func (c *Ring) ShardByName(name string) *ringShard { + return c.sharding.ShardByName(name) } -func (c *ringShards) GetAddr(addr string) *ringShard { - return c.shards[addr] +func (c *ringSharding) ShardByName(name string) *ringShard { + return c.shards.m[name] } diff --git a/ring.go b/ring.go index 65c7ce89ee..a8e08df08b 100644 --- a/ring.go +++ b/ring.go @@ -48,8 +48,8 @@ type RingOptions struct { // Map of name => host:port addresses of ring shards. Addrs map[string]string - // NewClient creates a shard client with provided name and options. - NewClient func(name string, opt *Options) *Client + // NewClient creates a shard client with provided options. + NewClient func(opt *Options) *Client // Frequency of PING commands sent to check shards availability. // Shard is considered down after 3 subsequent failed checks. @@ -95,7 +95,7 @@ type RingOptions struct { func (opt *RingOptions) init() { if opt.NewClient == nil { - opt.NewClient = func(name string, opt *Options) *Client { + opt.NewClient = func(opt *Options) *Client { return NewClient(opt) } } @@ -163,12 +163,12 @@ type ringShard struct { addr string } -func newRingShard(opt *RingOptions, name, addr string) *ringShard { +func newRingShard(opt *RingOptions, addr string) *ringShard { clopt := opt.clientOptions() clopt.Addr = addr return &ringShard{ - Client: opt.NewClient(name, clopt), + Client: opt.NewClient(clopt), addr: addr, } } @@ -210,20 +210,23 @@ func (shard *ringShard) Vote(up bool) bool { //------------------------------------------------------------------------------ -type ringShards struct { +type ringSharding struct { opt *RingOptions mu sync.RWMutex - muClose sync.Mutex + shards *ringShards + closed bool hash ConsistentHash - shards map[string]*ringShard // read only, updated by SetAddrs - list []*ringShard // read only, updated by SetAddrs numShard int - closed bool } -func newRingShards(opt *RingOptions) *ringShards { - c := &ringShards{ +type ringShards struct { + m map[string]*ringShard + list []*ringShard +} + +func newRingSharding(opt *RingOptions) *ringSharding { + c := &ringSharding{ opt: opt, } c.SetAddrs(opt.Addrs) @@ -234,63 +237,75 @@ func newRingShards(opt *RingOptions) *ringShards { // SetAddrs replaces the shards in use, such that you can increase and // decrease number of shards, that you use. It will reuse shards that // existed before and close the ones that will not be used anymore. -func (c *ringShards) SetAddrs(addrs map[string]string) { - c.muClose.Lock() - defer c.muClose.Unlock() +func (c *ringSharding) SetAddrs(addrs map[string]string) { + c.mu.Lock() + if c.closed { + c.mu.Unlock() return } - shards := make(map[string]*ringShard) - unusedShards := make(map[string]*ringShard) + shards, cleanup := newRingShards(c.opt, addrs, c.shards) + c.shards = shards + c.mu.Unlock() - for k, shard := range c.shards { - if addr, ok := addrs[k]; ok && shard.addr == addr { - shards[k] = shard - } else { - unusedShards[k] = shard - } - } + c.rebalance() + cleanup() +} + +func newRingShards( + opt *RingOptions, addrs map[string]string, existingShards *ringShards, +) (*ringShards, func()) { + shardMap := make(map[string]*ringShard) // indexed by addr + unusedShards := make(map[string]*ringShard) // indexed by addr - for k, addr := range addrs { - if shard, ok := c.shards[k]; !ok || shard.addr != addr { - shards[k] = newRingShard(c.opt, k, addr) + if existingShards != nil { + for _, shard := range existingShards.list { + addr := shard.Client.opt.Addr + shardMap[addr] = shard + unusedShards[addr] = shard } } - list := make([]*ringShard, 0, len(shards)) - for _, shard := range shards { - list = append(list, shard) + shards := &ringShards{ + m: make(map[string]*ringShard), } - c.mu.Lock() - c.shards = shards - c.list = list + for name, addr := range addrs { + if shard, ok := shardMap[addr]; ok { + shards.m[name] = shard + delete(unusedShards, addr) + } else { + shards.m[name] = newRingShard(opt, addr) + } + } - c.rebalanceLocked() - c.mu.Unlock() + for _, shard := range shards.m { + shards.list = append(shards.list, shard) + } - for k, shard := range unusedShards { - err := shard.Client.Close() - if err != nil { - internal.Logger.Printf(context.Background(), "Failed to close ring shard client %s %s: %v", k, shard.addr, err) + return shards, func() { + for addr, shard := range unusedShards { + if err := shard.Client.Close(); err != nil { + internal.Logger.Printf(context.Background(), "shard.Close %s failed: %s", addr, err) + } } } } -func (c *ringShards) List() []*ringShard { +func (c *ringSharding) List() []*ringShard { var list []*ringShard c.mu.RLock() if !c.closed { - list = c.list + list = c.shards.list } c.mu.RUnlock() return list } -func (c *ringShards) Hash(key string) string { +func (c *ringSharding) Hash(key string) string { key = hashtag.Key(key) var hash string @@ -305,7 +320,7 @@ func (c *ringShards) Hash(key string) string { return hash } -func (c *ringShards) GetByKey(key string) (*ringShard, error) { +func (c *ringSharding) GetByKey(key string) (*ringShard, error) { key = hashtag.Key(key) c.mu.RLock() @@ -319,15 +334,14 @@ func (c *ringShards) GetByKey(key string) (*ringShard, error) { return nil, errRingShardsDown } - hash := c.hash.Get(key) - if hash == "" { + shardName := c.hash.Get(key) + if shardName == "" { return nil, errRingShardsDown } - - return c.shards[hash], nil + return c.shards.m[shardName], nil } -func (c *ringShards) GetByName(shardName string) (*ringShard, error) { +func (c *ringSharding) GetByName(shardName string) (*ringShard, error) { if shardName == "" { return c.Random() } @@ -335,15 +349,15 @@ func (c *ringShards) GetByName(shardName string) (*ringShard, error) { c.mu.RLock() defer c.mu.RUnlock() - return c.shards[shardName], nil + return c.shards.m[shardName], nil } -func (c *ringShards) Random() (*ringShard, error) { +func (c *ringSharding) Random() (*ringShard, error) { return c.GetByKey(strconv.Itoa(rand.Int())) } // Heartbeat monitors state of each shard in the ring. -func (c *ringShards) Heartbeat(ctx context.Context, frequency time.Duration) { +func (c *ringSharding) Heartbeat(ctx context.Context, frequency time.Duration) { ticker := time.NewTicker(frequency) defer ticker.Stop() @@ -371,33 +385,18 @@ func (c *ringShards) Heartbeat(ctx context.Context, frequency time.Duration) { } // rebalance removes dead shards from the Ring. -func (c *ringShards) rebalance() { +func (c *ringSharding) rebalance() { c.mu.RLock() shards := c.shards c.mu.RUnlock() - liveShards := make([]string, 0, len(shards)) - - for name, shard := range shards { - if shard.IsUp() { - liveShards = append(liveShards, name) - } + if shards == nil { + return } - hash := c.opt.NewConsistentHash(liveShards) - - c.mu.Lock() - c.hash = hash - c.numShard = len(liveShards) - c.mu.Unlock() -} - -// rebalanceLocked removes dead shards from the Ring and callers need to hold the locl -func (c *ringShards) rebalanceLocked() { - shards := c.shards - liveShards := make([]string, 0, len(shards)) + liveShards := make([]string, 0, len(shards.m)) - for name, shard := range shards { + for name, shard := range shards.m { if shard.IsUp() { liveShards = append(liveShards, name) } @@ -405,20 +404,22 @@ func (c *ringShards) rebalanceLocked() { hash := c.opt.NewConsistentHash(liveShards) - c.hash = hash - c.numShard = len(liveShards) + c.mu.Lock() + if !c.closed { + c.hash = hash + c.numShard = len(liveShards) + } + c.mu.Unlock() } -func (c *ringShards) Len() int { +func (c *ringSharding) Len() int { c.mu.RLock() defer c.mu.RUnlock() return c.numShard } -func (c *ringShards) Close() error { - c.muClose.Lock() - defer c.muClose.Unlock() +func (c *ringSharding) Close() error { c.mu.Lock() defer c.mu.Unlock() @@ -428,7 +429,8 @@ func (c *ringShards) Close() error { c.closed = true var firstErr error - for _, shard := range c.shards { + + for _, shard := range c.shards.list { if err := shard.Client.Close(); err != nil && firstErr == nil { firstErr = err } @@ -437,20 +439,12 @@ func (c *ringShards) Close() error { c.hash = nil c.shards = nil c.numShard = 0 - c.list = nil return firstErr } //------------------------------------------------------------------------------ -type ring struct { - opt *RingOptions - shards *ringShards - cmdsInfoCache *cmdsInfoCache //nolint:structcheck - heartbeatCancelFn context.CancelFunc -} - // Ring is a Redis client that uses consistent hashing to distribute // keys across multiple Redis servers (shards). It's safe for // concurrent use by multiple goroutines. @@ -466,7 +460,11 @@ type ring struct { // and can tolerate losing data when one of the servers dies. // Otherwise you should use Redis Cluster. type Ring struct { - *ring + opt *RingOptions + sharding *ringSharding + cmdsInfoCache *cmdsInfoCache + heartbeatCancelFn context.CancelFunc + cmdable hooks } @@ -477,23 +475,21 @@ func NewRing(opt *RingOptions) *Ring { hbCtx, hbCancel := context.WithCancel(context.Background()) ring := Ring{ - ring: &ring{ - opt: opt, - shards: newRingShards(opt), - heartbeatCancelFn: hbCancel, - }, + opt: opt, + sharding: newRingSharding(opt), + heartbeatCancelFn: hbCancel, } ring.cmdsInfoCache = newCmdsInfoCache(ring.cmdsInfo) ring.cmdable = ring.Process - go ring.shards.Heartbeat(hbCtx, opt.HeartbeatFrequency) + go ring.sharding.Heartbeat(hbCtx, opt.HeartbeatFrequency) return &ring } -func (c *Ring) SetAddrs(ctx context.Context, addrs map[string]string) { - c.shards.SetAddrs(addrs) +func (c *Ring) SetAddrs(addrs map[string]string) { + c.sharding.SetAddrs(addrs) } // Do creates a Cmd from the args and processes the cmd. @@ -518,7 +514,7 @@ func (c *Ring) retryBackoff(attempt int) time.Duration { // PoolStats returns accumulated connection pool stats. func (c *Ring) PoolStats() *PoolStats { - shards := c.shards.List() + shards := c.sharding.List() var acc PoolStats for _, shard := range shards { s := shard.Client.connPool.Stats() @@ -533,7 +529,7 @@ func (c *Ring) PoolStats() *PoolStats { // Len returns the current number of shards in the ring. func (c *Ring) Len() int { - return c.shards.Len() + return c.sharding.Len() } // Subscribe subscribes the client to the specified channels. @@ -542,7 +538,7 @@ func (c *Ring) Subscribe(ctx context.Context, channels ...string) *PubSub { panic("at least one channel is required") } - shard, err := c.shards.GetByKey(channels[0]) + shard, err := c.sharding.GetByKey(channels[0]) if err != nil { // TODO: return PubSub with sticky error panic(err) @@ -556,7 +552,7 @@ func (c *Ring) PSubscribe(ctx context.Context, channels ...string) *PubSub { panic("at least one channel is required") } - shard, err := c.shards.GetByKey(channels[0]) + shard, err := c.sharding.GetByKey(channels[0]) if err != nil { // TODO: return PubSub with sticky error panic(err) @@ -570,7 +566,7 @@ func (c *Ring) ForEachShard( ctx context.Context, fn func(ctx context.Context, client *Client) error, ) error { - shards := c.shards.List() + shards := c.sharding.List() var wg sync.WaitGroup errCh := make(chan error, 1) for _, shard := range shards { @@ -601,7 +597,7 @@ func (c *Ring) ForEachShard( } func (c *Ring) cmdsInfo(ctx context.Context) (map[string]*CommandInfo, error) { - shards := c.shards.List() + shards := c.sharding.List() var firstErr error for _, shard := range shards { cmdsInfo, err := shard.Client.Command(ctx).Result() @@ -634,10 +630,10 @@ func (c *Ring) cmdShard(ctx context.Context, cmd Cmder) (*ringShard, error) { cmdInfo := c.cmdInfo(ctx, cmd.Name()) pos := cmdFirstKeyPos(cmd, cmdInfo) if pos == 0 { - return c.shards.Random() + return c.sharding.Random() } firstKey := cmd.stringArg(pos) - return c.shards.GetByKey(firstKey) + return c.sharding.GetByKey(firstKey) } func (c *Ring) process(ctx context.Context, cmd Cmder) error { @@ -706,7 +702,7 @@ func (c *Ring) generalProcessPipeline( cmdInfo := c.cmdInfo(ctx, cmd.Name()) hash := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo)) if hash != "" { - hash = c.shards.Hash(hash) + hash = c.sharding.Hash(hash) } cmdsMap[hash] = append(cmdsMap[hash], cmd) } @@ -729,7 +725,7 @@ func (c *Ring) processShardPipeline( ctx context.Context, hash string, cmds []Cmder, tx bool, ) error { // TODO: retry? - shard, err := c.shards.GetByName(hash) + shard, err := c.sharding.GetByName(hash) if err != nil { setCmdsErr(cmds, err) return err @@ -749,7 +745,7 @@ func (c *Ring) Watch(ctx context.Context, fn func(*Tx) error, keys ...string) er var shards []*ringShard for _, key := range keys { if key != "" { - shard, err := c.shards.GetByKey(hashtag.Key(key)) + shard, err := c.sharding.GetByKey(hashtag.Key(key)) if err != nil { return err } @@ -781,5 +777,5 @@ func (c *Ring) Watch(ctx context.Context, fn func(*Tx) error, keys ...string) er func (c *Ring) Close() error { c.heartbeatCancelFn() - return c.shards.Close() + return c.sharding.Close() } diff --git a/ring_test.go b/ring_test.go index d80406282c..ed4d3ba361 100644 --- a/ring_test.go +++ b/ring_test.go @@ -117,26 +117,25 @@ var _ = Describe("Redis Ring", func() { It("downscale shard and check reuse shard, upscale shard and check reuse", func() { Expect(ring.Len(), 2) - wantShard := ring.GetAddr("ringShardOne") + wantShard := ring.ShardByName("ringShardOne") ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - ring.SetAddrs(ctx, map[string]string{ + ring.SetAddrs(map[string]string{ "ringShardOne": ":" + ringShard1Port, }) Expect(ring.Len(), 1) - gotShard := ring.GetAddr("ringShardOne") + gotShard := ring.ShardByName("ringShardOne") Expect(gotShard).To(Equal(wantShard)) ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - ring.SetAddrs(ctx, map[string]string{ + ring.SetAddrs(map[string]string{ "ringShardOne": ":" + ringShard1Port, "ringShardTwo": ":" + ringShard2Port, }) Expect(ring.Len(), 2) - gotShard = ring.GetAddr("ringShardOne") + gotShard = ring.ShardByName("ringShardOne") Expect(gotShard).To(Equal(wantShard)) - }) It("uses 3 shards after setting it to 3 shards", func() { @@ -149,42 +148,41 @@ var _ = Describe("Redis Ring", func() { shardName1 := "ringShardOne" shardAddr1 := ":" + ringShard1Port - wantShard1 := ring.GetAddr(shardName1) + wantShard1 := ring.ShardByName(shardName1) shardName2 := "ringShardTwo" shardAddr2 := ":" + ringShard2Port - wantShard2 := ring.GetAddr(shardName2) + wantShard2 := ring.ShardByName(shardName2) shardName3 := "ringShardThree" shardAddr3 := ":" + ringShard3Port ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - ring.SetAddrs(ctx, map[string]string{ + ring.SetAddrs(map[string]string{ shardName1: shardAddr1, shardName2: shardAddr2, shardName3: shardAddr3, }) Expect(ring.Len(), 3) - gotShard1 := ring.GetAddr(shardName1) - gotShard2 := ring.GetAddr(shardName2) - gotShard3 := ring.GetAddr(shardName3) + gotShard1 := ring.ShardByName(shardName1) + gotShard2 := ring.ShardByName(shardName2) + gotShard3 := ring.ShardByName(shardName3) Expect(gotShard1).To(Equal(wantShard1)) Expect(gotShard2).To(Equal(wantShard2)) Expect(gotShard3).ToNot(BeNil()) ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - ring.SetAddrs(ctx, map[string]string{ + ring.SetAddrs(map[string]string{ shardName1: shardAddr1, shardName2: shardAddr2, }) Expect(ring.Len(), 2) - gotShard1 = ring.GetAddr(shardName1) - gotShard2 = ring.GetAddr(shardName2) - gotShard3 = ring.GetAddr(shardName3) + gotShard1 = ring.ShardByName(shardName1) + gotShard2 = ring.ShardByName(shardName2) + gotShard3 = ring.ShardByName(shardName3) Expect(gotShard1).To(Equal(wantShard1)) Expect(gotShard2).To(Equal(wantShard2)) Expect(gotShard3).To(BeNil()) }) - }) Describe("pipeline", func() { It("doesn't panic closed ring, returns error", func() { @@ -263,7 +261,7 @@ var _ = Describe("Redis Ring", func() { Describe("new client callback", func() { It("can be initialized with a new client callback", func() { opts := redisRingOptions() - opts.NewClient = func(name string, opt *redis.Options) *redis.Client { + opts.NewClient = func(opt *redis.Options) *redis.Client { opt.Username = "username1" opt.Password = "password1" return redis.NewClient(opt) From 20ba6d59e61dbabb130f692a38d6cf2831e0205c Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Wed, 17 Aug 2022 13:24:22 +0300 Subject: [PATCH 072/621] chore: cleanup --- ring_test.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/ring_test.go b/ring_test.go index ed4d3ba361..e0f58b237d 100644 --- a/ring_test.go +++ b/ring_test.go @@ -118,8 +118,6 @@ var _ = Describe("Redis Ring", func() { Expect(ring.Len(), 2) wantShard := ring.ShardByName("ringShardOne") - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() ring.SetAddrs(map[string]string{ "ringShardOne": ":" + ringShard1Port, }) @@ -127,8 +125,6 @@ var _ = Describe("Redis Ring", func() { gotShard := ring.ShardByName("ringShardOne") Expect(gotShard).To(Equal(wantShard)) - ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() ring.SetAddrs(map[string]string{ "ringShardOne": ":" + ringShard1Port, "ringShardTwo": ":" + ringShard2Port, @@ -145,6 +141,7 @@ var _ = Describe("Redis Ring", func() { var err error ringShard3, err = startRedis(ringShard3Port) Expect(err).NotTo(HaveOccurred()) + defer ringShard3.Close() shardName1 := "ringShardOne" shardAddr1 := ":" + ringShard1Port @@ -154,8 +151,7 @@ var _ = Describe("Redis Ring", func() { wantShard2 := ring.ShardByName(shardName2) shardName3 := "ringShardThree" shardAddr3 := ":" + ringShard3Port - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() + ring.SetAddrs(map[string]string{ shardName1: shardAddr1, shardName2: shardAddr2, @@ -169,8 +165,6 @@ var _ = Describe("Redis Ring", func() { Expect(gotShard2).To(Equal(wantShard2)) Expect(gotShard3).ToNot(BeNil()) - ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() ring.SetAddrs(map[string]string{ shardName1: shardAddr1, shardName2: shardAddr2, From 63392a363ad7dce4c1b5aae60d1207104664371b Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Fri, 26 Aug 2022 20:55:45 +1000 Subject: [PATCH 073/621] fix: return early when context signals done --- sentinel.go | 75 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/sentinel.go b/sentinel.go index a2dbcce4ec..bdf1c39f6c 100644 --- a/sentinel.go +++ b/sentinel.go @@ -472,8 +472,15 @@ func (c *sentinelFailover) MasterAddr(ctx context.Context) (string, error) { c.mu.RUnlock() if sentinel != nil { - addr := c.getMasterAddr(ctx, sentinel) - if addr != "" { + addr, err := c.getMasterAddr(ctx, sentinel) + if err != nil { + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return "", err + } + // Continue on other errors + internal.Logger.Printf(ctx, "sentinel: GetMasterAddrByName name=%q failed: %s", + c.opt.MasterName, err) + } else { return addr, nil } } @@ -482,11 +489,18 @@ func (c *sentinelFailover) MasterAddr(ctx context.Context) (string, error) { defer c.mu.Unlock() if c.sentinel != nil { - addr := c.getMasterAddr(ctx, c.sentinel) - if addr != "" { + addr, err := c.getMasterAddr(ctx, c.sentinel) + if err != nil { + _ = c.closeSentinel() + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return "", err + } + // Continue on other errors + internal.Logger.Printf(ctx, "sentinel: GetMasterAddrByName name=%q failed: %s", + c.opt.MasterName, err) + } else { return addr, nil } - _ = c.closeSentinel() } for i, sentinelAddr := range c.sentinelAddrs { @@ -494,9 +508,12 @@ func (c *sentinelFailover) MasterAddr(ctx context.Context) (string, error) { masterAddr, err := sentinel.GetMasterAddrByName(ctx, c.opt.MasterName).Result() if err != nil { + _ = sentinel.Close() + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return "", err + } internal.Logger.Printf(ctx, "sentinel: GetMasterAddrByName master=%q failed: %s", c.opt.MasterName, err) - _ = sentinel.Close() continue } @@ -517,8 +534,15 @@ func (c *sentinelFailover) replicaAddrs(ctx context.Context, useDisconnected boo c.mu.RUnlock() if sentinel != nil { - addrs := c.getReplicaAddrs(ctx, sentinel) - if len(addrs) > 0 { + addrs, err := c.getReplicaAddrs(ctx, sentinel) + if err != nil { + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return nil, err + } + // Continue on other errors + internal.Logger.Printf(ctx, "sentinel: Replicas name=%q failed: %s", + c.opt.MasterName, err) + } else if len(addrs) > 0 { return addrs, nil } } @@ -527,11 +551,21 @@ func (c *sentinelFailover) replicaAddrs(ctx context.Context, useDisconnected boo defer c.mu.Unlock() if c.sentinel != nil { - addrs := c.getReplicaAddrs(ctx, c.sentinel) - if len(addrs) > 0 { + addrs, err := c.getReplicaAddrs(ctx, c.sentinel) + if err != nil { + _ = c.closeSentinel() + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return nil, err + } + // Continue on other errors + internal.Logger.Printf(ctx, "sentinel: Replicas name=%q failed: %s", + c.opt.MasterName, err) + } else if len(addrs) > 0 { return addrs, nil + } else { + // No error and no replicas. + _ = c.closeSentinel() } - _ = c.closeSentinel() } var sentinelReachable bool @@ -541,9 +575,12 @@ func (c *sentinelFailover) replicaAddrs(ctx context.Context, useDisconnected boo replicas, err := sentinel.Replicas(ctx, c.opt.MasterName).Result() if err != nil { + _ = sentinel.Close() + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return nil, err + } internal.Logger.Printf(ctx, "sentinel: Replicas master=%q failed: %s", c.opt.MasterName, err) - _ = sentinel.Close() continue } sentinelReachable = true @@ -564,24 +601,22 @@ func (c *sentinelFailover) replicaAddrs(ctx context.Context, useDisconnected boo return []string{}, errors.New("redis: all sentinels specified in configuration are unreachable") } -func (c *sentinelFailover) getMasterAddr(ctx context.Context, sentinel *SentinelClient) string { +func (c *sentinelFailover) getMasterAddr(ctx context.Context, sentinel *SentinelClient) (string, error) { addr, err := sentinel.GetMasterAddrByName(ctx, c.opt.MasterName).Result() if err != nil { - internal.Logger.Printf(ctx, "sentinel: GetMasterAddrByName name=%q failed: %s", - c.opt.MasterName, err) - return "" + return "", err } - return net.JoinHostPort(addr[0], addr[1]) + return net.JoinHostPort(addr[0], addr[1]), nil } -func (c *sentinelFailover) getReplicaAddrs(ctx context.Context, sentinel *SentinelClient) []string { +func (c *sentinelFailover) getReplicaAddrs(ctx context.Context, sentinel *SentinelClient) ([]string, error) { addrs, err := sentinel.Replicas(ctx, c.opt.MasterName).Result() if err != nil { internal.Logger.Printf(ctx, "sentinel: Replicas name=%q failed: %s", c.opt.MasterName, err) - return nil + return nil, err } - return parseReplicaAddrs(addrs, false) + return parseReplicaAddrs(addrs, false), nil } func parseReplicaAddrs(addrs []map[string]string, keepDisconnected bool) []string { From c99340abb0a56ca7d60deb6bd1a13763f180870c Mon Sep 17 00:00:00 2001 From: tison Date: Thu, 1 Sep 2022 16:00:37 +0800 Subject: [PATCH 074/621] chore: correct Kvrocks spells and new repo location (#2202) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 468cf10b79..3941808703 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ for your applications thanks to its per request pricing and low latency data. - [Redis Cache](https://github.com/go-redis/cache) - [Rate limiting](https://github.com/go-redis/redis_rate) -This client also works with [kvrocks](https://github.com/KvrocksLabs/kvrocks), a distributed key +This client also works with [Kvrocks](https://github.com/apache/incubator-kvrocks), a distributed key value NoSQL database that uses RocksDB as storage engine and is compatible with Redis protocol. ## Features From 0f5495d469204af726aa1386b60693e720b53063 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Sep 2022 12:36:28 +0000 Subject: [PATCH 075/621] chore(deps): bump github.com/onsi/gomega from 1.20.0 to 1.20.2 Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.20.0 to 1.20.2. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.20.0...v1.20.2) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 6 +++--- go.sum | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 927841e0d3..08694d0ff4 100644 --- a/go.mod +++ b/go.mod @@ -6,15 +6,15 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.20.0 + github.com/onsi/gomega v1.20.2 ) require ( github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/google/go-cmp v0.5.8 // indirect github.com/nxadm/tail v1.4.8 // indirect - golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect - golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect + golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect + golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect golang.org/x/text v0.3.7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 224bfa9034..3524872a8d 100644 --- a/go.sum +++ b/go.sum @@ -39,25 +39,29 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= -github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY= +github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -67,12 +71,14 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -89,8 +95,10 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -102,6 +110,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 4dcf3cca728baf872ae7516d1bb4bef65ad9df37 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Thu, 15 Sep 2022 12:01:14 +0300 Subject: [PATCH 076/621] chore: update readme --- README.md | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 3941808703..46bff5ea12 100644 --- a/README.md +++ b/README.md @@ -6,22 +6,9 @@ [![Chat](https://discordapp.com/api/guilds/752070105847955518/widget.png)](https://discord.gg/rWtp5Aj) > go-redis is brought to you by :star: [**uptrace/uptrace**](https://github.com/uptrace/uptrace). -> Uptrace is an open source and blazingly fast -> [distributed tracing tool](https://get.uptrace.dev/compare/distributed-tracing-tools.html) powered -> by OpenTelemetry and ClickHouse. Give it a star as well! - -## Sponsors - -### Upstash: Serverless Database for Redis - -Upstash - -Upstash is a Serverless Database with Redis/REST API and durable storage. It is the perfect database -for your applications thanks to its per request pricing and low latency data. - -[Start for free in 30 seconds!](https://upstash.com/?utm_source=goredis) - -
+> Uptrace is an open-source APM tool that supports distributed tracing, metrics, and logs. You can +> use it to monitor applications and set up automatic alerts to receive notifications via email, +> Slack, Telegram, and others. Star it as well! ## Resources @@ -38,8 +25,8 @@ for your applications thanks to its per request pricing and low latency data. - [Redis Cache](https://github.com/go-redis/cache) - [Rate limiting](https://github.com/go-redis/redis_rate) -This client also works with [Kvrocks](https://github.com/apache/incubator-kvrocks), a distributed key -value NoSQL database that uses RocksDB as storage engine and is compatible with Redis protocol. +This client also works with [Kvrocks](https://github.com/apache/incubator-kvrocks), a distributed +key value NoSQL database that uses RocksDB as storage engine and is compatible with Redis protocol. ## Features From c0a6f2d724206dcddade8359e8559cc93f528a2b Mon Sep 17 00:00:00 2001 From: Leo Antunes Date: Fri, 16 Sep 2022 13:18:55 +0200 Subject: [PATCH 077/621] chore(redisotel): bump deps --- extra/redisotel/go.mod | 6 +++--- extra/redisotel/go.sum | 16 ++++++---------- extra/redisotel/redisotel.go | 2 +- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/extra/redisotel/go.mod b/extra/redisotel/go.mod index 4677366b97..885dac25eb 100644 --- a/extra/redisotel/go.mod +++ b/extra/redisotel/go.mod @@ -9,7 +9,7 @@ replace github.com/go-redis/redis/extra/rediscmd/v9 => ../rediscmd require ( github.com/go-redis/redis/extra/rediscmd/v9 v9.0.0-beta.2 github.com/go-redis/redis/v9 v9.0.0-beta.2 - go.opentelemetry.io/otel v1.8.0 - go.opentelemetry.io/otel/sdk v1.4.1 - go.opentelemetry.io/otel/trace v1.8.0 + go.opentelemetry.io/otel v1.10.0 + go.opentelemetry.io/otel/sdk v1.10.0 + go.opentelemetry.io/otel/trace v1.10.0 ) diff --git a/extra/redisotel/go.sum b/extra/redisotel/go.sum index 3e6357a7dd..c9f8f8f242 100644 --- a/extra/redisotel/go.sum +++ b/extra/redisotel/go.sum @@ -31,7 +31,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -58,19 +57,16 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdTiUde4= -go.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg= -go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= -go.opentelemetry.io/otel/sdk v1.4.1 h1:J7EaW71E0v87qflB4cDolaqq3AcujGrtyIPGQoZOB0Y= -go.opentelemetry.io/otel/sdk v1.4.1/go.mod h1:NBwHDgDIBYjwK2WNu1OPgsIc2IJzmBXNnvIJxJc8BpE= -go.opentelemetry.io/otel/trace v1.4.1/go.mod h1:iYEVbroFCNut9QkwEczV9vMRPHNKSSwYZjulEtsmhFc= -go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY= -go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= +go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= +go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpTNdY= +go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= +go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= +go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/extra/redisotel/redisotel.go b/extra/redisotel/redisotel.go index 53f7ec3a01..4594206930 100644 --- a/extra/redisotel/redisotel.go +++ b/extra/redisotel/redisotel.go @@ -6,7 +6,7 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + semconv "go.opentelemetry.io/otel/semconv/v1.10.0" "go.opentelemetry.io/otel/trace" "github.com/go-redis/redis/extra/rediscmd/v9" From d56af1f2d1fc45e5c577f50051d61cd8064d5bc6 Mon Sep 17 00:00:00 2001 From: tison Date: Sat, 24 Sep 2022 11:28:14 +0800 Subject: [PATCH 078/621] feat: support eval_ro and evalsha_ro Signed-off-by: tison --- command.go | 2 +- commands.go | 31 +++++++++++++++++-------------- commands_test.go | 23 +++++++++++++++++++++++ script.go | 20 ++++++++++++++++++++ 4 files changed, 61 insertions(+), 15 deletions(-) diff --git a/command.go b/command.go index d4fc91de8e..59cd8a6c64 100644 --- a/command.go +++ b/command.go @@ -65,7 +65,7 @@ func cmdFirstKeyPos(cmd Cmder, info *CommandInfo) int { } switch cmd.Name() { - case "eval", "evalsha": + case "eval", "evalsha", "eval_ro", "evalsha_ro": if cmd.stringArg(2) != "0" { return 3 } diff --git a/commands.go b/commands.go index 57de25b0ac..01f3e6163e 100644 --- a/commands.go +++ b/commands.go @@ -339,6 +339,8 @@ type Cmdable interface { Eval(ctx context.Context, script string, keys []string, args ...interface{}) *Cmd EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *Cmd + EvalRO(ctx context.Context, script string, keys []string, args ...interface{}) *Cmd + EvalShaRO(ctx context.Context, sha1 string, keys []string, args ...interface{}) *Cmd ScriptExists(ctx context.Context, hashes ...string) *BoolSliceCmd ScriptFlush(ctx context.Context) *StatusCmd ScriptKill(ctx context.Context) *StatusCmd @@ -3010,24 +3012,25 @@ func (c cmdable) MemoryUsage(ctx context.Context, key string, samples ...int) *I //------------------------------------------------------------------------------ func (c cmdable) Eval(ctx context.Context, script string, keys []string, args ...interface{}) *Cmd { - cmdArgs := make([]interface{}, 3+len(keys), 3+len(keys)+len(args)) - cmdArgs[0] = "eval" - cmdArgs[1] = script - cmdArgs[2] = len(keys) - for i, key := range keys { - cmdArgs[3+i] = key - } - cmdArgs = appendArgs(cmdArgs, args) - cmd := NewCmd(ctx, cmdArgs...) - cmd.SetFirstKeyPos(3) - _ = c(ctx, cmd) - return cmd + return c.eval(ctx, "eval", script, keys, args...) +} + +func (c cmdable) EvalRO(ctx context.Context, script string, keys []string, args ...interface{}) *Cmd { + return c.eval(ctx, "eval_ro", script, keys, args...) } func (c cmdable) EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *Cmd { + return c.eval(ctx, "evalsha", sha1, keys, args...) +} + +func (c cmdable) EvalShaRO(ctx context.Context, sha1 string, keys []string, args ...interface{}) *Cmd { + return c.eval(ctx, "evalsha_ro", sha1, keys, args...) +} + +func (c cmdable) eval(ctx context.Context, name, payload string, keys []string, args ...interface{}) *Cmd { cmdArgs := make([]interface{}, 3+len(keys), 3+len(keys)+len(args)) - cmdArgs[0] = "evalsha" - cmdArgs[1] = sha1 + cmdArgs[0] = name + cmdArgs[1] = payload cmdArgs[2] = len(keys) for i, key := range keys { cmdArgs[3+i] = key diff --git a/commands_test.go b/commands_test.go index fd5f9c7595..2551c33a9e 100644 --- a/commands_test.go +++ b/commands_test.go @@ -5413,6 +5413,29 @@ var _ = Describe("Commands", func() { }) }) + Describe("EvalRO", func() { + It("returns keys and values", func() { + vals, err := client.EvalRO( + ctx, + "return {KEYS[1],ARGV[1]}", + []string{"key"}, + "hello", + ).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(vals).To(Equal([]interface{}{"key", "hello"})) + }) + + It("returns all values after an error", func() { + vals, err := client.EvalRO( + ctx, + `return {12, {err="error"}, "abc"}`, + nil, + ).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(vals).To(Equal([]interface{}{int64(12), proto.RedisError("error"), "abc"})) + }) + }) + Describe("SlowLogGet", func() { It("returns slow query result", func() { const key = "slowlog-log-slower-than" diff --git a/script.go b/script.go index 5cab18d617..b0425b7611 100644 --- a/script.go +++ b/script.go @@ -11,6 +11,8 @@ import ( type Scripter interface { Eval(ctx context.Context, script string, keys []string, args ...interface{}) *Cmd EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *Cmd + EvalRO(ctx context.Context, script string, keys []string, args ...interface{}) *Cmd + EvalShaRO(ctx context.Context, sha1 string, keys []string, args ...interface{}) *Cmd ScriptExists(ctx context.Context, hashes ...string) *BoolSliceCmd ScriptLoad(ctx context.Context, script string) *StringCmd } @@ -50,10 +52,18 @@ func (s *Script) Eval(ctx context.Context, c Scripter, keys []string, args ...in return c.Eval(ctx, s.src, keys, args...) } +func (s *Script) EvalRO(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd { + return c.EvalRO(ctx, s.src, keys, args...) +} + func (s *Script) EvalSha(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd { return c.EvalSha(ctx, s.hash, keys, args...) } +func (s *Script) EvalShaRO(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd { + return c.EvalShaRO(ctx, s.hash, keys, args...) +} + // Run optimistically uses EVALSHA to run the script. If script does not exist // it is retried using EVAL. func (s *Script) Run(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd { @@ -63,3 +73,13 @@ func (s *Script) Run(ctx context.Context, c Scripter, keys []string, args ...int } return r } + +// RunRO optimistically uses EVALSHA_RO to run the script. If script does not exist +// it is retried using EVAL_RO. +func (s *Script) RunRO(ctx context.Context, c Scripter, keys []string, args ...interface{}) *Cmd { + r := s.EvalShaRO(ctx, c, keys, args...) + if err := r.Err(); err != nil && strings.HasPrefix(err.Error(), "NOSCRIPT ") { + return s.EvalRO(ctx, c, keys, args...) + } + return r +} From 77dabc301912331567d6c554196003da48840d5f Mon Sep 17 00:00:00 2001 From: Rusty Magnet <5367141+rustymagnet3000@users.noreply.github.com> Date: Tue, 4 Oct 2022 13:05:14 +0100 Subject: [PATCH 079/621] docs: another ScanType example with "Hash" as the KeyType (#2212) * docs: example ScanType call that passes in Hash and gets all keys * docs: added further example_scantype * docs: updated comment of ExampleClient_ScanType_Type_Hash --- example_test.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/example_test.go b/example_test.go index 56cf9018f3..2626b9aa64 100644 --- a/example_test.go +++ b/example_test.go @@ -278,6 +278,36 @@ func ExampleClient_ScanType() { // Output: found 33 keys } +// ExampleClient_ScanType_Type_Hash uses the KeyType "hash" +// Uses ScanType toZZ loop through lots of "keys" in Redis, 10 at a time, and add each key to a []string +func ExampleClient_ScanType_Type_Hash() { + rdb.FlushDB(ctx) + for i := 0; i < 33; i++ { + err := rdb.HSet(context.TODO(), fmt.Sprintf("key%d", i), "value", "foo").Err() + if err != nil { + panic(err) + } + } + + var allKeys []string + var cursor uint64 + var err error + + for { + var keysFromScan []string + keysFromScan, cursor, err = rdb.ScanType(context.TODO(), cursor, "key*", 10, "hash").Result() + if err != nil { + panic(err) + } + allKeys = append(allKeys, keysFromScan...) + if cursor == 0 { + break + } + } + fmt.Printf("%d keys ready for use\n", len(allKeys)) + // Output: 33 keys ready for use\n +} + // ExampleMapStringStringCmd_Scan shows how to scan the results of a map fetch // into a struct. func ExampleMapStringStringCmd_Scan() { From aaba70a3a733b880d299f5381febed6885f63019 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Tue, 4 Oct 2022 15:09:05 +0300 Subject: [PATCH 080/621] chore: fix example --- example_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example_test.go b/example_test.go index 2626b9aa64..ce508b92d5 100644 --- a/example_test.go +++ b/example_test.go @@ -304,8 +304,8 @@ func ExampleClient_ScanType_Type_Hash() { break } } - fmt.Printf("%d keys ready for use\n", len(allKeys)) - // Output: 33 keys ready for use\n + fmt.Printf("%d keys ready for use", len(allKeys)) + // Output: 33 keys ready for use } // ExampleMapStringStringCmd_Scan shows how to scan the results of a map fetch From 3129e09b29f37ac8b8a1256deef1883140dbb255 Mon Sep 17 00:00:00 2001 From: Mitch Usher Date: Thu, 25 Aug 2022 20:07:47 -0600 Subject: [PATCH 081/621] Update redis otel with option to not set raw command as an attribute --- extra/redisotel/redisotel.go | 39 +++++++++++++++++++++---------- extra/redisotel/redisotel_test.go | 27 +++++++++++++++++++++ 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/extra/redisotel/redisotel.go b/extra/redisotel/redisotel.go index 53f7ec3a01..94759ebcd6 100644 --- a/extra/redisotel/redisotel.go +++ b/extra/redisotel/redisotel.go @@ -18,8 +18,9 @@ const ( ) type TracingHook struct { - tracer trace.Tracer - attrs []attribute.KeyValue + tracer trace.Tracer + attrs []attribute.KeyValue + dbStmtEnabled bool } func NewTracingHook(opts ...Option) *TracingHook { @@ -28,6 +29,7 @@ func NewTracingHook(opts ...Option) *TracingHook { attrs: []attribute.KeyValue{ semconv.DBSystemRedis, }, + dbStmtEnabled: true, } for _, opt := range opts { opt.apply(cfg) @@ -37,7 +39,7 @@ func NewTracingHook(opts ...Option) *TracingHook { defaultTracerName, trace.WithInstrumentationVersion("semver:"+redis.Version()), ) - return &TracingHook{tracer: tracer, attrs: cfg.attrs} + return &TracingHook{tracer: tracer, attrs: cfg.attrs, dbStmtEnabled: cfg.dbStmtEnabled} } func (th *TracingHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (context.Context, error) { @@ -48,9 +50,10 @@ func (th *TracingHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (cont opts := []trace.SpanStartOption{ trace.WithSpanKind(trace.SpanKindClient), trace.WithAttributes(th.attrs...), - trace.WithAttributes( - semconv.DBStatementKey.String(rediscmd.CmdString(cmd)), - ), + } + + if th.dbStmtEnabled { + opts = append(opts, trace.WithAttributes(semconv.DBStatementKey.String(rediscmd.CmdString(cmd)))) } ctx, _ = th.tracer.Start(ctx, cmd.FullName(), opts...) @@ -67,22 +70,26 @@ func (th *TracingHook) AfterProcess(ctx context.Context, cmd redis.Cmder) error return nil } -func (th *TracingHook) BeforeProcessPipeline(ctx context.Context, cmds []redis.Cmder) (context.Context, error) { +func (th *TracingHook) BeforeProcessPipeline( + ctx context.Context, cmds []redis.Cmder, +) (context.Context, error) { if !trace.SpanFromContext(ctx).IsRecording() { return ctx, nil } - summary, cmdsString := rediscmd.CmdsString(cmds) - opts := []trace.SpanStartOption{ trace.WithSpanKind(trace.SpanKindClient), trace.WithAttributes(th.attrs...), trace.WithAttributes( - semconv.DBStatementKey.String(cmdsString), attribute.Int("db.redis.num_cmd", len(cmds)), ), } + summary, cmdsString := rediscmd.CmdsString(cmds) + if th.dbStmtEnabled { + opts = append(opts, trace.WithAttributes(semconv.DBStatementKey.String(cmdsString))) + } + ctx, _ = th.tracer.Start(ctx, "pipeline "+summary, opts...) return ctx, nil @@ -105,8 +112,9 @@ func recordError(ctx context.Context, span trace.Span, err error) { } type config struct { - tp trace.TracerProvider - attrs []attribute.KeyValue + tp trace.TracerProvider + attrs []attribute.KeyValue + dbStmtEnabled bool } // Option specifies instrumentation configuration options. @@ -136,3 +144,10 @@ func WithAttributes(attrs ...attribute.KeyValue) Option { cfg.attrs = append(cfg.attrs, attrs...) }) } + +// WithDBStatement tells the tracing hook not to log raw redis commands. +func WithDBStatement(on bool) Option { + return optionFunc(func(cfg *config) { + cfg.dbStmtEnabled = on + }) +} diff --git a/extra/redisotel/redisotel_test.go b/extra/redisotel/redisotel_test.go index 4de0e7137f..8c0e4871c9 100644 --- a/extra/redisotel/redisotel_test.go +++ b/extra/redisotel/redisotel_test.go @@ -68,3 +68,30 @@ func TestNewWithAttributes(t *testing.T) { t.Fatalf("expected attrs[2] to be semconv.DBStatementKey.String(\"ping\"), got: %v", attrs[2]) } } + +func TestWithDBStatement(t *testing.T) { + provider := sdktrace.NewTracerProvider() + hook := redisotel.NewTracingHook( + redisotel.WithTracerProvider(provider), + redisotel.WithDBStatement(false), + ) + ctx, span := provider.Tracer("redis-test").Start(context.TODO(), "redis-test") + cmd := redis.NewCmd(ctx, "ping") + defer span.End() + + ctx, err := hook.BeforeProcess(ctx, cmd) + if err != nil { + t.Fatal(err) + } + err = hook.AfterProcess(ctx, cmd) + if err != nil { + t.Fatal(err) + } + + attrs := trace.SpanFromContext(ctx).(sdktrace.ReadOnlySpan).Attributes() + for _, attr := range attrs { + if attr.Key == semconv.DBStatementKey { + t.Fatal("Attribute with db statement should not exist") + } + } +} From 2bcb060d6a122849ad19ad47900f8ad9db8aefeb Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Wed, 5 Oct 2022 10:06:54 +0300 Subject: [PATCH 082/621] chore: update example --- example_test.go | 5 ++--- extra/redisotel/go.sum | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/example_test.go b/example_test.go index ce508b92d5..f63339714a 100644 --- a/example_test.go +++ b/example_test.go @@ -278,9 +278,8 @@ func ExampleClient_ScanType() { // Output: found 33 keys } -// ExampleClient_ScanType_Type_Hash uses the KeyType "hash" -// Uses ScanType toZZ loop through lots of "keys" in Redis, 10 at a time, and add each key to a []string -func ExampleClient_ScanType_Type_Hash() { +// ExampleClient_ScanType_hashType uses the keyType "hash". +func ExampleClient_ScanType_hashType() { rdb.FlushDB(ctx) for i := 0; i < 33; i++ { err := rdb.HSet(context.TODO(), fmt.Sprintf("key%d", i), "value", "foo").Err() diff --git a/extra/redisotel/go.sum b/extra/redisotel/go.sum index c9f8f8f242..efdc47f604 100644 --- a/extra/redisotel/go.sum +++ b/extra/redisotel/go.sum @@ -45,14 +45,17 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY= +github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -61,6 +64,7 @@ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMT github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpTNdY= @@ -73,6 +77,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -82,12 +87,14 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -105,8 +112,10 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -118,6 +127,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From bac50ce2e953769cb93f1a4e044253c744afa3cc Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Wed, 5 Oct 2022 10:36:12 +0300 Subject: [PATCH 083/621] chore: allow to disable timeouts --- internal/pool/conn.go | 12 ++++++++---- options.go | 22 +++++++++++++++++----- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/internal/pool/conn.go b/internal/pool/conn.go index 5b5079a585..f160a9fa6f 100644 --- a/internal/pool/conn.go +++ b/internal/pool/conn.go @@ -64,8 +64,10 @@ func (cn *Conn) RemoteAddr() net.Addr { } func (cn *Conn) WithReader(ctx context.Context, timeout time.Duration, fn func(rd *proto.Reader) error) error { - if err := cn.netConn.SetReadDeadline(cn.deadline(ctx, timeout)); err != nil { - return err + if timeout >= 0 { + if err := cn.netConn.SetReadDeadline(cn.deadline(ctx, timeout)); err != nil { + return err + } } return fn(cn.rd) } @@ -73,8 +75,10 @@ func (cn *Conn) WithReader(ctx context.Context, timeout time.Duration, fn func(r func (cn *Conn) WithWriter( ctx context.Context, timeout time.Duration, fn func(wr *proto.Writer) error, ) error { - if err := cn.netConn.SetWriteDeadline(cn.deadline(ctx, timeout)); err != nil { - return err + if timeout >= 0 { + if err := cn.netConn.SetWriteDeadline(cn.deadline(ctx, timeout)); err != nil { + return err + } } if cn.bw.Buffered() > 0 { diff --git a/options.go b/options.go index 0c2cb1d1f8..bc8d3cb8ac 100644 --- a/options.go +++ b/options.go @@ -72,12 +72,16 @@ type Options struct { // Default is 5 seconds. DialTimeout time.Duration // Timeout for socket reads. If reached, commands will fail - // with a timeout instead of blocking. Use value -1 for no timeout and 0 for default. - // Default is 3 seconds. + // with a timeout instead of blocking. Supported values: + // - `0` - default timeout (3 seconds). + // - `-1` - no timeout (block indefinitely). + // - `-2` - disables SetReadDeadline calls completely. ReadTimeout time.Duration // Timeout for socket writes. If reached, commands will fail - // with a timeout instead of blocking. Use value -1 for no timeout and 0 for default. - // Default is ReadTimeout. + // with a timeout instead of blocking. Supported values: + // - `0` - default timeout (3 seconds). + // - `-1` - no timeout (block indefinitely). + // - `-2` - disables SetWriteDeadline calls completely. WriteTimeout time.Duration // Type of connection pool. @@ -144,19 +148,27 @@ func (opt *Options) init() { opt.PoolSize = 10 * runtime.GOMAXPROCS(0) } switch opt.ReadTimeout { + case -2: + opt.ReadTimeout = -1 case -1: opt.ReadTimeout = 0 case 0: opt.ReadTimeout = 3 * time.Second } switch opt.WriteTimeout { + case -2: + opt.WriteTimeout = -1 case -1: opt.WriteTimeout = 0 case 0: opt.WriteTimeout = opt.ReadTimeout } if opt.PoolTimeout == 0 { - opt.PoolTimeout = opt.ReadTimeout + time.Second + if opt.ReadTimeout > 0 { + opt.PoolTimeout = opt.ReadTimeout + time.Second + } else { + opt.PoolTimeout = 30 * time.Second + } } if opt.ConnMaxIdleTime == 0 { opt.ConnMaxIdleTime = 30 * time.Minute From fea57be18ffb069553de9a6e175ff1da8159eabf Mon Sep 17 00:00:00 2001 From: j178 <10510431+j178@users.noreply.github.com> Date: Thu, 6 Oct 2022 04:33:53 +0800 Subject: [PATCH 084/621] fix(pubsub): fix break introduced by #2177 --- commands.go | 6 +++--- ring.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/commands.go b/commands.go index 0a89baf207..cfd69106a7 100644 --- a/commands.go +++ b/commands.go @@ -352,7 +352,7 @@ type Cmdable interface { PubSubNumSub(ctx context.Context, channels ...string) *MapStringIntCmd PubSubNumPat(ctx context.Context) *IntCmd PubSubShardChannels(ctx context.Context, pattern string) *StringSliceCmd - PubSubShardNumSub(ctx context.Context, channels ...string) *StringIntMapCmd + PubSubShardNumSub(ctx context.Context, channels ...string) *MapStringIntCmd ClusterSlots(ctx context.Context) *ClusterSlotsCmd ClusterNodes(ctx context.Context) *StringCmd @@ -3122,14 +3122,14 @@ func (c cmdable) PubSubShardChannels(ctx context.Context, pattern string) *Strin return cmd } -func (c cmdable) PubSubShardNumSub(ctx context.Context, channels ...string) *StringIntMapCmd { +func (c cmdable) PubSubShardNumSub(ctx context.Context, channels ...string) *MapStringIntCmd { args := make([]interface{}, 2+len(channels)) args[0] = "pubsub" args[1] = "shardnumsub" for i, channel := range channels { args[2+i] = channel } - cmd := NewStringIntMapCmd(ctx, args...) + cmd := NewMapStringIntCmd(ctx, args...) _ = c(ctx, cmd) return cmd } diff --git a/ring.go b/ring.go index 0ae7e645ad..fa916c6caf 100644 --- a/ring.go +++ b/ring.go @@ -565,7 +565,7 @@ func (c *Ring) SSubscribe(ctx context.Context, channels ...string) *PubSub { if len(channels) == 0 { panic("at least one channel is required") } - shard, err := c.shards.GetByKey(channels[0]) + shard, err := c.sharding.GetByKey(channels[0]) if err != nil { // TODO: return PubSub with sticky error panic(err) From b0231c659e7ea25cce065318fe3bea8e996441d4 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Thu, 6 Oct 2022 10:06:02 +0300 Subject: [PATCH 085/621] chore: always retry write timeouts --- README.md | 2 +- main_test.go | 3 +-- redis.go | 3 +++ ring_test.go | 6 ------ 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 46bff5ea12..5235566345 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Redis client for Go -![build workflow](https://github.com/go-redis/redis/actions/workflows/build.yml/badge.svg) +[![build workflow](https://github.com/go-redis/redis/actions/workflows/build.yml/badge.svg)](https://github.com/go-redis/redis/actions) [![PkgGoDev](https://pkg.go.dev/badge/github.com/go-redis/redis/v8)](https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc) [![Documentation](https://img.shields.io/badge/redis-documentation-informational)](https://redis.uptrace.dev/) [![Chat](https://discordapp.com/api/guilds/752070105847955518/widget.png)](https://discord.gg/rWtp5Aj) diff --git a/main_test.go b/main_test.go index 24ba02ec4d..b63a09e08f 100644 --- a/main_test.go +++ b/main_test.go @@ -2,7 +2,6 @@ package redis_test import ( "context" - "errors" "fmt" "net" "os" @@ -269,7 +268,7 @@ func (p *redisProcess) Close() error { if err := p.Client.Ping(ctx).Err(); err != nil { return nil } - return errors.New("client is not shutdown") + return fmt.Errorf("client %s is not shutdown", p.Options().Addr) }, 10*time.Second) if err != nil { return err diff --git a/redis.go b/redis.go index 84928d9bec..704d9e5156 100644 --- a/redis.go +++ b/redis.go @@ -341,6 +341,7 @@ func (c *baseClient) _process(ctx context.Context, cmd Cmder, attempt int) (bool return writeCmd(wr, cmd) }) if err != nil { + atomic.StoreUint32(&retryTimeout, 1) return err } @@ -348,6 +349,8 @@ func (c *baseClient) _process(ctx context.Context, cmd Cmder, attempt int) (bool if err != nil { if cmd.readTimeout() == nil { atomic.StoreUint32(&retryTimeout, 1) + } else { + atomic.StoreUint32(&retryTimeout, 0) } return err } diff --git a/ring_test.go b/ring_test.go index e0f58b237d..9610066c8a 100644 --- a/ring_test.go +++ b/ring_test.go @@ -137,12 +137,6 @@ var _ = Describe("Redis Ring", func() { It("uses 3 shards after setting it to 3 shards", func() { Expect(ring.Len(), 2) - // Start ringShard3. - var err error - ringShard3, err = startRedis(ringShard3Port) - Expect(err).NotTo(HaveOccurred()) - defer ringShard3.Close() - shardName1 := "ringShardOne" shardAddr1 := ":" + ringShard1Port wantShard1 := ring.ShardByName(shardName1) From a65f5edea0f1f2876eaa72d97e712bd2b7ff8a07 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Thu, 6 Oct 2022 10:25:00 +0300 Subject: [PATCH 086/621] chore: rename DefaultDialer to NewDialer --- options.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/options.go b/options.go index 138d50b465..c2f9c64cd6 100644 --- a/options.go +++ b/options.go @@ -133,7 +133,7 @@ func (opt *Options) init() { opt.DialTimeout = 5 * time.Second } if opt.Dialer == nil { - opt.Dialer = DefaultDialer(opt) + opt.Dialer = NewDialer(opt) } if opt.PoolSize == 0 { opt.PoolSize = 10 * runtime.GOMAXPROCS(0) @@ -189,9 +189,9 @@ func (opt *Options) clone() *Options { return &clone } -// DefaultDialer returns a function that will be used as the default dialer +// NewDialer returns a function that will be used as the default dialer // when none is specified in Options.Dialer. -func DefaultDialer(opt *Options) func(context.Context, string, string) (net.Conn, error) { +func NewDialer(opt *Options) func(context.Context, string, string) (net.Conn, error) { return func(ctx context.Context, network, addr string) (net.Conn, error) { netDialer := &net.Dialer{ Timeout: opt.DialTimeout, From 6327c52e60cabd2acb43dcacab389def4e3e9a5a Mon Sep 17 00:00:00 2001 From: Stephanie Hingtgen Date: Thu, 6 Oct 2022 05:33:37 -0500 Subject: [PATCH 087/621] Add ParseURL function for cluster mode (#1924) * feat: add ParseClusterURL to allow for parsing of redis cluster urls into cluster options --- cluster.go | 120 ++++++++++++++++++++++++++++++++++++++++- cluster_test.go | 139 ++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 4 ++ go.sum | 49 ++--------------- options.go | 35 ++++++++---- options_test.go | 8 +-- 6 files changed, 295 insertions(+), 60 deletions(-) diff --git a/cluster.go b/cluster.go index ea312284c4..2759d8fd14 100644 --- a/cluster.go +++ b/cluster.go @@ -6,8 +6,10 @@ import ( "fmt" "math" "net" + "net/url" "runtime" "sort" + "strings" "sync" "sync/atomic" "time" @@ -131,6 +133,123 @@ func (opt *ClusterOptions) init() { } } +// ParseClusterURL parses a URL into ClusterOptions that can be used to connect to Redis. +// The URL must be in the form: +// redis://:@: +// or +// rediss://:@: +// To add additional addresses, specify the query parameter, "addr" one or more times. e.g: +// redis://:@:?addr=:&addr=: +// or +// rediss://:@:?addr=:&addr=: +// +// Most Option fields can be set using query parameters, with the following restrictions: +// - field names are mapped using snake-case conversion: to set MaxRetries, use max_retries +// - only scalar type fields are supported (bool, int, time.Duration) +// - for time.Duration fields, values must be a valid input for time.ParseDuration(); +// additionally a plain integer as value (i.e. without unit) is intepreted as seconds +// - to disable a duration field, use value less than or equal to 0; to use the default +// value, leave the value blank or remove the parameter +// - only the last value is interpreted if a parameter is given multiple times +// - fields "network", "addr", "username" and "password" can only be set using other +// URL attributes (scheme, host, userinfo, resp.), query paremeters using these +// names will be treated as unknown parameters +// - unknown parameter names will result in an error +// Example: +// redis://user:password@localhost:6789?dial_timeout=3&read_timeout=6s&addr=localhost:6790&addr=localhost:6791 +// is equivalent to: +// &ClusterOptions{ +// Addr: ["localhost:6789", "localhost:6790", "localhost:6791"] +// DialTimeout: 3 * time.Second, // no time unit = seconds +// ReadTimeout: 6 * time.Second, +// } +func ParseClusterURL(redisURL string) (*ClusterOptions, error) { + o := &ClusterOptions{} + + u, err := url.Parse(redisURL) + if err != nil { + return nil, err + } + + // add base URL to the array of addresses + // more addresses may be added through the URL params + h, p := getHostPortWithDefaults(u) + o.Addrs = append(o.Addrs, net.JoinHostPort(h, p)) + + // setup username, password, and other configurations + o, err = setupClusterConn(u, h, o) + if err != nil { + return nil, err + } + + return o, nil +} + +// setupClusterConn gets the username and password from the URL and the query parameters. +func setupClusterConn(u *url.URL, host string, o *ClusterOptions) (*ClusterOptions, error) { + switch u.Scheme { + case "rediss": + o.TLSConfig = &tls.Config{ServerName: host} + fallthrough + case "redis": + o.Username, o.Password = getUserPassword(u) + default: + return nil, fmt.Errorf("redis: invalid URL scheme: %s", u.Scheme) + } + + // retrieve the configuration from the query parameters + o, err := setupClusterQueryParams(u, o) + if err != nil { + return nil, err + } + + return o, nil +} + +// setupClusterQueryParams converts query parameters in u to option value in o. +func setupClusterQueryParams(u *url.URL, o *ClusterOptions) (*ClusterOptions, error) { + q := queryOptions{q: u.Query()} + + o.MaxRedirects = q.int("max_redirects") + o.ReadOnly = q.bool("read_only") + o.RouteByLatency = q.bool("route_by_latency") + o.RouteByLatency = q.bool("route_randomly") + o.MaxRetries = q.int("max_retries") + o.MinRetryBackoff = q.duration("min_retry_backoff") + o.MaxRetryBackoff = q.duration("max_retry_backoff") + o.DialTimeout = q.duration("dial_timeout") + o.ReadTimeout = q.duration("read_timeout") + o.WriteTimeout = q.duration("write_timeout") + o.PoolFIFO = q.bool("pool_fifo") + o.PoolSize = q.int("pool_size") + o.MinIdleConns = q.int("min_idle_conns") + o.PoolTimeout = q.duration("pool_timeout") + o.ConnMaxLifetime = q.duration("conn_max_lifetime") + o.ConnMaxIdleTime = q.duration("conn_max_idle_time") + + if q.err != nil { + return nil, q.err + } + + // addr can be specified as many times as needed + addrs := q.strings("addr") + for _, addr := range addrs { + h, p, err := net.SplitHostPort(addr) + if err != nil || h == "" || p == "" { + return nil, fmt.Errorf("redis: unable to parse addr param: %s", addr) + } + + o.Addrs = append(o.Addrs, net.JoinHostPort(h, p)) + } + + // any parameters left? + if r := q.remaining(); len(r) > 0 { + return nil, fmt.Errorf("redis: unexpected option: %s", strings.Join(r, ", ")) + } + + return o, nil +} + func (opt *ClusterOptions) clientOptions() *Options { return &Options{ Dialer: opt.Dialer, @@ -1537,7 +1656,6 @@ func (c *ClusterClient) SSubscribe(ctx context.Context, channels ...string) *Pub return pubsub } - func (c *ClusterClient) retryBackoff(attempt int) time.Duration { return internal.RetryBackoff(attempt, c.opt.MinRetryBackoff, c.opt.MaxRetryBackoff) } diff --git a/cluster_test.go b/cluster_test.go index e503ea84ff..72938a2ba1 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -2,15 +2,19 @@ package redis_test import ( "context" + "crypto/tls" + "errors" "fmt" "net" "strconv" "strings" "sync" + "testing" "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/stretchr/testify/assert" "github.com/go-redis/redis/v9" "github.com/go-redis/redis/v9/internal/hashtag" @@ -1296,3 +1300,138 @@ var _ = Describe("ClusterClient timeout", func() { testTimeout() }) }) + +func TestParseClusterURL(t *testing.T) { + cases := []struct { + test string + url string + o *redis.ClusterOptions // expected value + err error + }{ + { + test: "ParseRedisURL", + url: "redis://localhost:123", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}}, + }, { + test: "ParseRedissURL", + url: "rediss://localhost:123", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}, TLSConfig: &tls.Config{ServerName: "localhost"}}, + }, { + test: "MissingRedisPort", + url: "redis://localhost", + o: &redis.ClusterOptions{Addrs: []string{"localhost:6379"}}, + }, { + test: "MissingRedissPort", + url: "rediss://localhost", + o: &redis.ClusterOptions{Addrs: []string{"localhost:6379"}, TLSConfig: &tls.Config{ServerName: "localhost"}}, + }, { + test: "MultipleRedisURLs", + url: "redis://localhost:123?addr=localhost:1234&addr=localhost:12345", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123", "localhost:1234", "localhost:12345"}}, + }, { + test: "MultipleRedissURLs", + url: "rediss://localhost:123?addr=localhost:1234&addr=localhost:12345", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123", "localhost:1234", "localhost:12345"}, TLSConfig: &tls.Config{ServerName: "localhost"}}, + }, { + test: "OnlyPassword", + url: "redis://:bar@localhost:123", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}, Password: "bar"}, + }, { + test: "OnlyUser", + url: "redis://foo@localhost:123", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}, Username: "foo"}, + }, { + test: "RedisUsernamePassword", + url: "redis://foo:bar@localhost:123", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}, Username: "foo", Password: "bar"}, + }, { + test: "RedissUsernamePassword", + url: "rediss://foo:bar@localhost:123?addr=localhost:1234", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123", "localhost:1234"}, Username: "foo", Password: "bar", TLSConfig: &tls.Config{ServerName: "localhost"}}, + }, { + test: "QueryParameters", + url: "redis://localhost:123?read_timeout=2&pool_fifo=true&addr=localhost:1234", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123", "localhost:1234"}, ReadTimeout: 2 * time.Second, PoolFIFO: true}, + }, { + test: "DisabledTimeout", + url: "redis://localhost:123?conn_max_idle_time=0", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}, ConnMaxIdleTime: -1}, + }, { + test: "DisabledTimeoutNeg", + url: "redis://localhost:123?conn_max_idle_time=-1", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}, ConnMaxIdleTime: -1}, + }, { + test: "UseDefault", + url: "redis://localhost:123?conn_max_idle_time=", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}, ConnMaxIdleTime: 0}, + }, { + test: "UseDefaultMissing=", + url: "redis://localhost:123?conn_max_idle_time", + o: &redis.ClusterOptions{Addrs: []string{"localhost:123"}, ConnMaxIdleTime: 0}, + }, { + test: "InvalidQueryAddr", + url: "rediss://foo:bar@localhost:123?addr=rediss://foo:barr@localhost:1234", + err: errors.New(`redis: unable to parse addr param: rediss://foo:barr@localhost:1234`), + }, { + test: "InvalidInt", + url: "redis://localhost?pool_size=five", + err: errors.New(`redis: invalid pool_size number: strconv.Atoi: parsing "five": invalid syntax`), + }, { + test: "InvalidBool", + url: "redis://localhost?pool_fifo=yes", + err: errors.New(`redis: invalid pool_fifo boolean: expected true/false/1/0 or an empty string, got "yes"`), + }, { + test: "UnknownParam", + url: "redis://localhost?abc=123", + err: errors.New("redis: unexpected option: abc"), + }, { + test: "InvalidScheme", + url: "https://google.com", + err: errors.New("redis: invalid URL scheme: https"), + }, + } + + for i := range cases { + tc := cases[i] + t.Run(tc.test, func(t *testing.T) { + t.Parallel() + + actual, err := redis.ParseClusterURL(tc.url) + if tc.err == nil && err != nil { + t.Fatalf("unexpected error: %q", err) + return + } + if tc.err != nil && err == nil { + t.Fatalf("expected error: got %+v", actual) + return + } + if tc.err != nil && err != nil { + if tc.err.Error() != err.Error() { + t.Fatalf("got %q, expected %q", err, tc.err) + } + return + } + comprareOptions(t, actual, tc.o) + }) + } +} + +func comprareOptions(t *testing.T, actual, expected *redis.ClusterOptions) { + t.Helper() + assert.Equal(t, expected.Addrs, actual.Addrs) + assert.Equal(t, expected.TLSConfig, actual.TLSConfig) + assert.Equal(t, expected.Username, actual.Username) + assert.Equal(t, expected.Password, actual.Password) + assert.Equal(t, expected.MaxRetries, actual.MaxRetries) + assert.Equal(t, expected.MinRetryBackoff, actual.MinRetryBackoff) + assert.Equal(t, expected.MaxRetryBackoff, actual.MaxRetryBackoff) + assert.Equal(t, expected.DialTimeout, actual.DialTimeout) + assert.Equal(t, expected.ReadTimeout, actual.ReadTimeout) + assert.Equal(t, expected.WriteTimeout, actual.WriteTimeout) + assert.Equal(t, expected.PoolFIFO, actual.PoolFIFO) + assert.Equal(t, expected.PoolSize, actual.PoolSize) + assert.Equal(t, expected.MinIdleConns, actual.MinIdleConns) + assert.Equal(t, expected.ConnMaxLifetime, actual.ConnMaxLifetime) + assert.Equal(t, expected.ConnMaxIdleTime, actual.ConnMaxIdleTime) + assert.Equal(t, expected.PoolTimeout, actual.PoolTimeout) +} diff --git a/go.mod b/go.mod index 08694d0ff4..bc8294b743 100644 --- a/go.mod +++ b/go.mod @@ -7,15 +7,19 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.20.2 + github.com/stretchr/testify v1.5.1 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/google/go-cmp v0.5.8 // indirect github.com/nxadm/tail v1.4.8 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect golang.org/x/text v0.3.7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v2 v2.3.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3524872a8d..6c39f42e06 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,7 @@ github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= @@ -18,99 +16,63 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= -github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY= github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -121,10 +83,7 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -132,7 +91,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/options.go b/options.go index c2f9c64cd6..56791289ed 100644 --- a/options.go +++ b/options.go @@ -255,16 +255,7 @@ func setupTCPConn(u *url.URL) (*Options, error) { o.Username, o.Password = getUserPassword(u) - h, p, err := net.SplitHostPort(u.Host) - if err != nil { - h = u.Host - } - if h == "" { - h = "localhost" - } - if p == "" { - p = "6379" - } + h, p := getHostPortWithDefaults(u) o.Addr = net.JoinHostPort(h, p) f := strings.FieldsFunc(u.Path, func(r rune) bool { @@ -274,6 +265,7 @@ func setupTCPConn(u *url.URL) (*Options, error) { case 0: o.DB = 0 case 1: + var err error if o.DB, err = strconv.Atoi(f[0]); err != nil { return nil, fmt.Errorf("redis: invalid database number: %q", f[0]) } @@ -291,6 +283,23 @@ func setupTCPConn(u *url.URL) (*Options, error) { return setupConnParams(u, o) } +// getHostPortWithDefaults is a helper function that splits the url into +// a host and a port. If the host is missing, it defaults to localhost +// and if the port is missing, it defaults to 6379. +func getHostPortWithDefaults(u *url.URL) (string, string) { + host, port, err := net.SplitHostPort(u.Host) + if err != nil { + host = u.Host + } + if host == "" { + host = "localhost" + } + if port == "" { + port = "6379" + } + return host, port +} + func setupUnixConn(u *url.URL) (*Options, error) { o := &Options{ Network: "unix", @@ -322,6 +331,12 @@ func (o *queryOptions) string(name string) string { return vs[len(vs)-1] } +func (o *queryOptions) strings(name string) []string { + vs := o.q[name] + delete(o.q, name) + return vs +} + func (o *queryOptions) int(name string) int { s := o.string(name) if s == "" { diff --git a/options_test.go b/options_test.go index f9c69a480b..47fa9cbc9a 100644 --- a/options_test.go +++ b/options_test.go @@ -46,18 +46,18 @@ func TestParseURL(t *testing.T) { o: &Options{Addr: "localhost:123", DB: 2, ReadTimeout: 2 * time.Second, PoolFIFO: true}, }, { // special case handling for disabled timeouts - url: "redis://localhost:123/?db=2&idle_timeout=0", + url: "redis://localhost:123/?db=2&conn_max_idle_time=0", o: &Options{Addr: "localhost:123", DB: 2, ConnMaxIdleTime: -1}, }, { // negative values disable timeouts as well - url: "redis://localhost:123/?db=2&idle_timeout=-1", + url: "redis://localhost:123/?db=2&conn_max_idle_time=-1", o: &Options{Addr: "localhost:123", DB: 2, ConnMaxIdleTime: -1}, }, { // absent timeout values will use defaults - url: "redis://localhost:123/?db=2&idle_timeout=", + url: "redis://localhost:123/?db=2&conn_max_idle_time=", o: &Options{Addr: "localhost:123", DB: 2, ConnMaxIdleTime: 0}, }, { - url: "redis://localhost:123/?db=2&idle_timeout", // missing "=" at the end + url: "redis://localhost:123/?db=2&conn_max_idle_time", // missing "=" at the end o: &Options{Addr: "localhost:123", DB: 2, ConnMaxIdleTime: 0}, }, { url: "unix:///tmp/redis.sock", From dd9a200427d7c57e480d61833a7204b13b55acbd Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Thu, 6 Oct 2022 14:05:55 +0300 Subject: [PATCH 088/621] fix: improve pipelines retry logic (#2232) * fix: improve pipelines retry logic --- cluster.go | 111 ++++++++++++++++++++++-------------------------- cluster_test.go | 21 +++++++-- race_test.go | 21 --------- redis.go | 68 ++++++++++++----------------- 4 files changed, 96 insertions(+), 125 deletions(-) diff --git a/cluster.go b/cluster.go index 2759d8fd14..f962684ff7 100644 --- a/cluster.go +++ b/cluster.go @@ -1180,8 +1180,8 @@ func (c *ClusterClient) processPipeline(ctx context.Context, cmds []Cmder) error func (c *ClusterClient) _processPipeline(ctx context.Context, cmds []Cmder) error { cmdsMap := newCmdsMap() - err := c.mapCmdsByNode(ctx, cmdsMap, cmds) - if err != nil { + + if err := c.mapCmdsByNode(ctx, cmdsMap, cmds); err != nil { setCmdsErr(cmds, err) return err } @@ -1201,18 +1201,7 @@ func (c *ClusterClient) _processPipeline(ctx context.Context, cmds []Cmder) erro wg.Add(1) go func(node *clusterNode, cmds []Cmder) { defer wg.Done() - - err := c._processPipelineNode(ctx, node, cmds, failedCmds) - if err == nil { - return - } - if attempt < c.opt.MaxRedirects { - if err := c.mapCmdsByNode(ctx, failedCmds, cmds); err != nil { - setCmdsErr(cmds, err) - } - } else { - setCmdsErr(cmds, err) - } + c._processPipelineNode(ctx, node, cmds, failedCmds) }(node, cmds) } @@ -1267,13 +1256,13 @@ func (c *ClusterClient) cmdsAreReadOnly(ctx context.Context, cmds []Cmder) bool func (c *ClusterClient) _processPipelineNode( ctx context.Context, node *clusterNode, cmds []Cmder, failedCmds *cmdsMap, -) error { - return node.Client.hooks.processPipeline(ctx, cmds, func(ctx context.Context, cmds []Cmder) error { +) { + _ = node.Client.hooks.processPipeline(ctx, cmds, func(ctx context.Context, cmds []Cmder) error { return node.Client.withConn(ctx, func(ctx context.Context, cn *pool.Conn) error { - err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error { + if err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error { return writeCmds(wr, cmds) - }) - if err != nil { + }); err != nil { + setCmdsErr(cmds, err) return err } @@ -1291,7 +1280,7 @@ func (c *ClusterClient) pipelineReadCmds( cmds []Cmder, failedCmds *cmdsMap, ) error { - for _, cmd := range cmds { + for i, cmd := range cmds { err := cmd.readReply(rd) cmd.SetErr(err) @@ -1303,15 +1292,24 @@ func (c *ClusterClient) pipelineReadCmds( continue } - if c.opt.ReadOnly && (isLoadingError(err) || !isRedisError(err)) { + if c.opt.ReadOnly { node.MarkAsFailing() - return err } - if isRedisError(err) { - continue + + if !isRedisError(err) { + if shouldRetry(err, true) { + _ = c.mapCmdsByNode(ctx, failedCmds, cmds) + } + setCmdsErr(cmds[i+1:], err) + return err } + } + + if err := cmds[0].Err(); err != nil && shouldRetry(err, true) { + _ = c.mapCmdsByNode(ctx, failedCmds, cmds) return err } + return nil } @@ -1393,19 +1391,7 @@ func (c *ClusterClient) _processTxPipeline(ctx context.Context, cmds []Cmder) er wg.Add(1) go func(node *clusterNode, cmds []Cmder) { defer wg.Done() - - err := c._processTxPipelineNode(ctx, node, cmds, failedCmds) - if err == nil { - return - } - - if attempt < c.opt.MaxRedirects { - if err := c.mapCmdsByNode(ctx, failedCmds, cmds); err != nil { - setCmdsErr(cmds, err) - } - } else { - setCmdsErr(cmds, err) - } + c._processTxPipelineNode(ctx, node, cmds, failedCmds) }(node, cmds) } @@ -1431,34 +1417,39 @@ func (c *ClusterClient) mapCmdsBySlot(ctx context.Context, cmds []Cmder) map[int func (c *ClusterClient) _processTxPipelineNode( ctx context.Context, node *clusterNode, cmds []Cmder, failedCmds *cmdsMap, -) error { - return node.Client.hooks.processTxPipeline(ctx, cmds, func(ctx context.Context, cmds []Cmder) error { - return node.Client.withConn(ctx, func(ctx context.Context, cn *pool.Conn) error { - err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error { - return writeCmds(wr, cmds) - }) - if err != nil { - return err - } - - return cn.WithReader(ctx, c.opt.ReadTimeout, func(rd *proto.Reader) error { - statusCmd := cmds[0].(*StatusCmd) - // Trim multi and exec. - cmds = cmds[1 : len(cmds)-1] - - err := c.txPipelineReadQueued(ctx, rd, statusCmd, cmds, failedCmds) - if err != nil { - moved, ask, addr := isMovedError(err) - if moved || ask { - return c.cmdsMoved(ctx, cmds, moved, ask, addr, failedCmds) - } +) { + _ = node.Client.hooks.processTxPipeline( + ctx, cmds, func(ctx context.Context, cmds []Cmder) error { + return node.Client.withConn(ctx, func(ctx context.Context, cn *pool.Conn) error { + if err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error { + return writeCmds(wr, cmds) + }); err != nil { + setCmdsErr(cmds, err) return err } - return pipelineReadCmds(rd, cmds) + return cn.WithReader(ctx, c.opt.ReadTimeout, func(rd *proto.Reader) error { + statusCmd := cmds[0].(*StatusCmd) + // Trim multi and exec. + trimmedCmds := cmds[1 : len(cmds)-1] + + if err := c.txPipelineReadQueued( + ctx, rd, statusCmd, trimmedCmds, failedCmds, + ); err != nil { + setCmdsErr(cmds, err) + + moved, ask, addr := isMovedError(err) + if moved || ask { + return c.cmdsMoved(ctx, trimmedCmds, moved, ask, addr, failedCmds) + } + + return err + } + + return pipelineReadCmds(rd, trimmedCmds) + }) }) }) - }) } func (c *ClusterClient) txPipelineReadQueued( diff --git a/cluster_test.go b/cluster_test.go index 72938a2ba1..92844eb684 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -1276,20 +1276,33 @@ var _ = Describe("ClusterClient timeout", func() { Context("read/write timeout", func() { BeforeEach(func() { opt := redisClusterOptions() - opt.ReadTimeout = 250 * time.Millisecond - opt.WriteTimeout = 250 * time.Millisecond - opt.MaxRedirects = 1 client = cluster.newClusterClient(ctx, opt) err := client.ForEachShard(ctx, func(ctx context.Context, client *redis.Client) error { - return client.ClientPause(ctx, pause).Err() + err := client.ClientPause(ctx, pause).Err() + + opt := client.Options() + opt.ReadTimeout = time.Nanosecond + opt.WriteTimeout = time.Nanosecond + + return err }) Expect(err).NotTo(HaveOccurred()) + + // Overwrite timeouts after the client is initialized. + opt.ReadTimeout = time.Nanosecond + opt.WriteTimeout = time.Nanosecond + opt.MaxRedirects = 0 }) AfterEach(func() { _ = client.ForEachShard(ctx, func(ctx context.Context, client *redis.Client) error { defer GinkgoRecover() + + opt := client.Options() + opt.ReadTimeout = time.Second + opt.WriteTimeout = time.Second + Eventually(func() error { return client.Ping(ctx).Err() }, 2*pause).ShouldNot(HaveOccurred()) diff --git a/race_test.go b/race_test.go index 52181e064f..2265366096 100644 --- a/race_test.go +++ b/race_test.go @@ -2,7 +2,6 @@ package redis_test import ( "bytes" - "context" "fmt" "net" "strconv" @@ -289,26 +288,6 @@ var _ = Describe("races", func() { wg.Wait() Expect(atomic.LoadUint32(&received)).To(Equal(uint32(C * N))) }) - - It("should abort on context timeout", func() { - opt := redisClusterOptions() - client := cluster.newClusterClient(ctx, opt) - - ctx, cancel := context.WithCancel(context.Background()) - - wg := performAsync(C, func(_ int) { - _, err := client.XRead(ctx, &redis.XReadArgs{ - Streams: []string{"test", "$"}, - Block: 1 * time.Second, - }).Result() - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Or(Equal(context.Canceled.Error()), ContainSubstring("operation was canceled"))) - }) - - time.Sleep(10 * time.Millisecond) - cancel() - wg.Wait() - }) }) var _ = Describe("cluster races", func() { diff --git a/redis.go b/redis.go index 704d9e5156..0428149332 100644 --- a/redis.go +++ b/redis.go @@ -290,27 +290,7 @@ func (c *baseClient) withConn( c.releaseConn(ctx, cn, err) }() - done := ctx.Done() //nolint:ifshort - - if done == nil { - err = fn(ctx, cn) - return err - } - - errc := make(chan error, 1) - go func() { errc <- fn(ctx, cn) }() - - select { - case <-done: - _ = cn.Close() - // Wait for the goroutine to finish and send something. - <-errc - - err = ctx.Err() - return err - case err = <-errc: - return err - } + return fn(ctx, cn) } func (c *baseClient) process(ctx context.Context, cmd Cmder) error { @@ -416,7 +396,6 @@ func (c *baseClient) generalProcessPipeline( ) error { err := c._generalProcessPipeline(ctx, cmds, p) if err != nil { - setCmdsErr(cmds, err) return err } return cmdsFirstErr(cmds) @@ -429,6 +408,7 @@ func (c *baseClient) _generalProcessPipeline( for attempt := 0; attempt <= c.opt.MaxRetries; attempt++ { if attempt > 0 { if err := internal.Sleep(ctx, c.retryBackoff(attempt)); err != nil { + setCmdsErr(cmds, err) return err } } @@ -449,53 +429,61 @@ func (c *baseClient) _generalProcessPipeline( func (c *baseClient) pipelineProcessCmds( ctx context.Context, cn *pool.Conn, cmds []Cmder, ) (bool, error) { - err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error { + if err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error { return writeCmds(wr, cmds) - }) - if err != nil { + }); err != nil { + setCmdsErr(cmds, err) return true, err } - err = cn.WithReader(ctx, c.opt.ReadTimeout, func(rd *proto.Reader) error { + if err := cn.WithReader(ctx, c.opt.ReadTimeout, func(rd *proto.Reader) error { return pipelineReadCmds(rd, cmds) - }) - return true, err + }); err != nil { + return true, err + } + + return false, nil } func pipelineReadCmds(rd *proto.Reader, cmds []Cmder) error { - for _, cmd := range cmds { + for i, cmd := range cmds { err := cmd.readReply(rd) cmd.SetErr(err) if err != nil && !isRedisError(err) { + setCmdsErr(cmds[i+1:], err) return err } } - return nil + // Retry errors like "LOADING redis is loading the dataset in memory". + return cmds[0].Err() } func (c *baseClient) txPipelineProcessCmds( ctx context.Context, cn *pool.Conn, cmds []Cmder, ) (bool, error) { - err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error { + if err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error { return writeCmds(wr, cmds) - }) - if err != nil { + }); err != nil { + setCmdsErr(cmds, err) return true, err } - err = cn.WithReader(ctx, c.opt.ReadTimeout, func(rd *proto.Reader) error { + if err := cn.WithReader(ctx, c.opt.ReadTimeout, func(rd *proto.Reader) error { statusCmd := cmds[0].(*StatusCmd) // Trim multi and exec. - cmds = cmds[1 : len(cmds)-1] + trimmedCmds := cmds[1 : len(cmds)-1] - err := txPipelineReadQueued(rd, statusCmd, cmds) - if err != nil { + if err := txPipelineReadQueued(rd, statusCmd, trimmedCmds); err != nil { + setCmdsErr(cmds, err) return err } - return pipelineReadCmds(rd, cmds) - }) - return false, err + return pipelineReadCmds(rd, trimmedCmds) + }); err != nil { + return false, err + } + + return false, nil } func wrapMultiExec(ctx context.Context, cmds []Cmder) []Cmder { From 28028b330fc11ea3f23fecd39a85828c4aa91a3e Mon Sep 17 00:00:00 2001 From: Simon Paredes Date: Fri, 7 Oct 2022 16:40:51 -0300 Subject: [PATCH 089/621] fix: use all provided sections --- commands.go | 31 ++++++++++++++++++------------- commands_test.go | 8 ++++++++ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/commands.go b/commands.go index cfd69106a7..d1e65ef744 100644 --- a/commands.go +++ b/commands.go @@ -13,7 +13,7 @@ import ( // otherwise you will receive an error: (error) ERR syntax error. // For example: // -// rdb.Set(ctx, key, value, redis.KeepTTL) +// rdb.Set(ctx, key, value, redis.KeepTTL) const KeepTTL = -1 func usePrecise(dur time.Duration) bool { @@ -2052,8 +2052,10 @@ func xClaimArgs(a *XClaimArgs) []interface{} { // xTrim If approx is true, add the "~" parameter, otherwise it is the default "=" (redis default). // example: -// XTRIM key MAXLEN/MINID threshold LIMIT limit. -// XTRIM key MAXLEN/MINID ~ threshold LIMIT limit. +// +// XTRIM key MAXLEN/MINID threshold LIMIT limit. +// XTRIM key MAXLEN/MINID ~ threshold LIMIT limit. +// // The redis-server version is lower than 6.2, please set limit to 0. func (c cmdable) xTrim( ctx context.Context, key, strategy string, @@ -2391,11 +2393,13 @@ func (c cmdable) ZPopMin(ctx context.Context, key string, count ...int64) *ZSlic // ZRangeArgs is all the options of the ZRange command. // In version> 6.2.0, you can replace the(cmd): -// ZREVRANGE, -// ZRANGEBYSCORE, -// ZREVRANGEBYSCORE, -// ZRANGEBYLEX, -// ZREVRANGEBYLEX. +// +// ZREVRANGE, +// ZRANGEBYSCORE, +// ZREVRANGEBYSCORE, +// ZRANGEBYLEX, +// ZREVRANGEBYLEX. +// // Please pay attention to your redis-server version. // // Rev, ByScore, ByLex and Offset+Count options require redis-server 6.2.0 and higher. @@ -2799,7 +2803,7 @@ func (c cmdable) ClientKill(ctx context.Context, ipPort string) *StatusCmd { // ClientKillByFilter is new style syntax, while the ClientKill is old // -// CLIENT KILL