diff options
Diffstat (limited to 'vendor/github.com/go-redis/redis')
17 files changed, 188 insertions, 53 deletions
diff --git a/vendor/github.com/go-redis/redis/.travis.yml b/vendor/github.com/go-redis/redis/.travis.yml index f49927ee8..c95b3e6c6 100644 --- a/vendor/github.com/go-redis/redis/.travis.yml +++ b/vendor/github.com/go-redis/redis/.travis.yml @@ -5,7 +5,6 @@ services: - redis-server go: - - 1.4.x - 1.7.x - 1.8.x - 1.9.x @@ -13,7 +12,6 @@ go: matrix: allow_failures: - - go: 1.4.x - go: tip install: diff --git a/vendor/github.com/go-redis/redis/README.md b/vendor/github.com/go-redis/redis/README.md index 0a2a67124..9f349764a 100644 --- a/vendor/github.com/go-redis/redis/README.md +++ b/vendor/github.com/go-redis/redis/README.md @@ -2,6 +2,7 @@ [![Build Status](https://travis-ci.org/go-redis/redis.png?branch=master)](https://travis-ci.org/go-redis/redis) [![GoDoc](https://godoc.org/github.com/go-redis/redis?status.svg)](https://godoc.org/github.com/go-redis/redis) +[![Airbrake](https://img.shields.io/badge/kudos-airbrake.io-orange.svg)](https://airbrake.io) Supports: @@ -66,14 +67,14 @@ func ExampleClient() { val2, err := client.Get("key2").Result() if err == redis.Nil { - fmt.Println("key2 does not exists") + fmt.Println("key2 does not exist") } else if err != nil { panic(err) } else { fmt.Println("key2", val2) } // Output: key value - // key2 does not exists + // key2 does not exist } ``` diff --git a/vendor/github.com/go-redis/redis/cluster.go b/vendor/github.com/go-redis/redis/cluster.go index c81fc1d57..accdb3d27 100644 --- a/vendor/github.com/go-redis/redis/cluster.go +++ b/vendor/github.com/go-redis/redis/cluster.go @@ -226,7 +226,7 @@ func (c *clusterNodes) NextGeneration() uint32 { } // GC removes unused nodes. -func (c *clusterNodes) GC(generation uint32) error { +func (c *clusterNodes) GC(generation uint32) { var collected []*clusterNode c.mu.Lock() for i := 0; i < len(c.addrs); { @@ -243,14 +243,11 @@ func (c *clusterNodes) GC(generation uint32) error { } c.mu.Unlock() - var firstErr error - for _, node := range collected { - if err := node.Client.Close(); err != nil && firstErr == nil { - firstErr = err + time.AfterFunc(time.Minute, func() { + for _, node := range collected { + _ = node.Client.Close() } - } - - return firstErr + }) } func (c *clusterNodes) All() ([]*clusterNode, error) { @@ -533,16 +530,22 @@ func (c *ClusterClient) cmdInfo(name string) *CommandInfo { return info } +func cmdSlot(cmd Cmder, pos int) int { + if pos == 0 { + return hashtag.RandomSlot() + } + firstKey := cmd.stringArg(pos) + return hashtag.Slot(firstKey) +} + func (c *ClusterClient) cmdSlot(cmd Cmder) int { cmdInfo := c.cmdInfo(cmd.Name()) - firstKey := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo)) - return hashtag.Slot(firstKey) + return cmdSlot(cmd, cmdFirstKeyPos(cmd, cmdInfo)) } func (c *ClusterClient) cmdSlotAndNode(state *clusterState, cmd Cmder) (int, *clusterNode, error) { cmdInfo := c.cmdInfo(cmd.Name()) - firstKey := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo)) - slot := hashtag.Slot(firstKey) + slot := cmdSlot(cmd, cmdFirstKeyPos(cmd, cmdInfo)) if cmdInfo != nil && cmdInfo.ReadOnly && c.opt.ReadOnly { if c.opt.RouteByLatency { @@ -590,6 +593,10 @@ func (c *ClusterClient) Watch(fn func(*Tx) error, keys ...string) error { break } + if internal.IsRetryableError(err, true) { + continue + } + moved, ask, addr := internal.IsMovedError(err) if moved || ask { c.lazyReloadState() @@ -600,6 +607,13 @@ func (c *ClusterClient) Watch(fn func(*Tx) error, keys ...string) error { continue } + if err == pool.ErrClosed { + node, err = state.slotMasterNode(slot) + if err != nil { + return err + } + } + return err } @@ -635,10 +649,10 @@ func (c *ClusterClient) Process(cmd Cmder) error { if ask { pipe := node.Client.Pipeline() - pipe.Process(NewCmd("ASKING")) - pipe.Process(cmd) + _ = pipe.Process(NewCmd("ASKING")) + _ = pipe.Process(cmd) _, err = pipe.Exec() - pipe.Close() + _ = pipe.Close() ask = false } else { err = node.Client.Process(cmd) @@ -679,6 +693,14 @@ func (c *ClusterClient) Process(cmd Cmder) error { continue } + if err == pool.ErrClosed { + _, node, err = c.cmdSlotAndNode(state, cmd) + if err != nil { + cmd.setErr(err) + return err + } + } + break } @@ -915,7 +937,11 @@ func (c *ClusterClient) pipelineExec(cmds []Cmder) error { for node, cmds := range cmdsMap { cn, _, err := node.Client.getConn() if err != nil { - setCmdsErr(cmds, err) + if err == pool.ErrClosed { + c.remapCmds(cmds, failedCmds) + } else { + setCmdsErr(cmds, err) + } continue } @@ -955,6 +981,18 @@ func (c *ClusterClient) mapCmdsByNode(cmds []Cmder) (map[*clusterNode][]Cmder, e return cmdsMap, nil } +func (c *ClusterClient) remapCmds(cmds []Cmder, failedCmds map[*clusterNode][]Cmder) { + remappedCmds, err := c.mapCmdsByNode(cmds) + if err != nil { + setCmdsErr(cmds, err) + return + } + + for node, cmds := range remappedCmds { + failedCmds[node] = cmds + } +} + func (c *ClusterClient) pipelineProcessCmds( node *clusterNode, cn *pool.Conn, cmds []Cmder, failedCmds map[*clusterNode][]Cmder, ) error { @@ -1061,7 +1099,11 @@ func (c *ClusterClient) txPipelineExec(cmds []Cmder) error { for node, cmds := range cmdsMap { cn, _, err := node.Client.getConn() if err != nil { - setCmdsErr(cmds, err) + if err == pool.ErrClosed { + c.remapCmds(cmds, failedCmds) + } else { + setCmdsErr(cmds, err) + } continue } diff --git a/vendor/github.com/go-redis/redis/cluster_test.go b/vendor/github.com/go-redis/redis/cluster_test.go index 6f3677b93..43f3261bc 100644 --- a/vendor/github.com/go-redis/redis/cluster_test.go +++ b/vendor/github.com/go-redis/redis/cluster_test.go @@ -536,6 +536,32 @@ var _ = Describe("ClusterClient", func() { Expect(nodesList).Should(HaveLen(1)) }) + It("should RANDOMKEY", func() { + const nkeys = 100 + + for i := 0; i < nkeys; i++ { + err := client.Set(fmt.Sprintf("key%d", i), "value", 0).Err() + Expect(err).NotTo(HaveOccurred()) + } + + var keys []string + addKey := func(key string) { + for _, k := range keys { + if k == key { + return + } + } + keys = append(keys, key) + } + + for i := 0; i < nkeys*10; i++ { + key := client.RandomKey().Val() + addKey(key) + } + + Expect(len(keys)).To(BeNumerically("~", nkeys, nkeys/10)) + }) + assertClusterClient() }) diff --git a/vendor/github.com/go-redis/redis/command.go b/vendor/github.com/go-redis/redis/command.go index d2688082a..598ed9800 100644 --- a/vendor/github.com/go-redis/redis/command.go +++ b/vendor/github.com/go-redis/redis/command.go @@ -82,13 +82,13 @@ func cmdFirstKeyPos(cmd Cmder, info *CommandInfo) int { if cmd.stringArg(2) != "0" { return 3 } else { - return -1 + return 0 } case "publish": return 1 } if info == nil { - return -1 + return 0 } return int(info.FirstKeyPos) } @@ -675,6 +675,44 @@ func (cmd *StringIntMapCmd) readReply(cn *pool.Conn) error { //------------------------------------------------------------------------------ +type StringStructMapCmd struct { + baseCmd + + val map[string]struct{} +} + +var _ Cmder = (*StringStructMapCmd)(nil) + +func NewStringStructMapCmd(args ...interface{}) *StringStructMapCmd { + return &StringStructMapCmd{ + baseCmd: baseCmd{_args: args}, + } +} + +func (cmd *StringStructMapCmd) Val() map[string]struct{} { + return cmd.val +} + +func (cmd *StringStructMapCmd) Result() (map[string]struct{}, error) { + return cmd.val, cmd.err +} + +func (cmd *StringStructMapCmd) String() string { + return cmdString(cmd, cmd.val) +} + +func (cmd *StringStructMapCmd) readReply(cn *pool.Conn) error { + var v interface{} + v, cmd.err = cn.Rd.ReadArrayReply(stringStructMapParser) + if cmd.err != nil { + return cmd.err + } + cmd.val = v.(map[string]struct{}) + return nil +} + +//------------------------------------------------------------------------------ + type ZSliceCmd struct { baseCmd diff --git a/vendor/github.com/go-redis/redis/commands.go b/vendor/github.com/go-redis/redis/commands.go index c04b3c49b..569342cfa 100644 --- a/vendor/github.com/go-redis/redis/commands.go +++ b/vendor/github.com/go-redis/redis/commands.go @@ -143,6 +143,7 @@ type Cmdable interface { SInterStore(destination string, keys ...string) *IntCmd SIsMember(key string, member interface{}) *BoolCmd SMembers(key string) *StringSliceCmd + SMembersMap(key string) *StringStructMapCmd SMove(source, destination string, member interface{}) *BoolCmd SPop(key string) *StringCmd SPopN(key string, count int64) *StringSliceCmd @@ -676,6 +677,7 @@ func (c *cmdable) DecrBy(key string, decrement int64) *IntCmd { return cmd } +// Redis `GET key` command. It returns redis.Nil error when key does not exist. func (c *cmdable) Get(key string) *StringCmd { cmd := NewStringCmd("get", key) c.process(cmd) @@ -1163,12 +1165,20 @@ func (c *cmdable) SIsMember(key string, member interface{}) *BoolCmd { return cmd } +// Redis `SMEMBERS key` command output as a slice func (c *cmdable) SMembers(key string) *StringSliceCmd { cmd := NewStringSliceCmd("smembers", key) c.process(cmd) return cmd } +// Redis `SMEMBERS key` command output as a map +func (c *cmdable) SMembersMap(key string) *StringStructMapCmd { + cmd := NewStringStructMapCmd("smembers", key) + c.process(cmd) + return cmd +} + func (c *cmdable) SMove(source, destination string, member interface{}) *BoolCmd { cmd := NewBoolCmd("smove", source, destination, member) c.process(cmd) diff --git a/vendor/github.com/go-redis/redis/commands_test.go b/vendor/github.com/go-redis/redis/commands_test.go index 6b81f23cf..715379556 100644 --- a/vendor/github.com/go-redis/redis/commands_test.go +++ b/vendor/github.com/go-redis/redis/commands_test.go @@ -1848,6 +1848,17 @@ var _ = Describe("Commands", func() { Expect(sMembers.Val()).To(ConsistOf([]string{"Hello", "World"})) }) + It("should SMembersMap", func() { + sAdd := client.SAdd("set", "Hello") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + sAdd = client.SAdd("set", "World") + Expect(sAdd.Err()).NotTo(HaveOccurred()) + + sMembersMap := client.SMembersMap("set") + Expect(sMembersMap.Err()).NotTo(HaveOccurred()) + Expect(sMembersMap.Val()).To(Equal(map[string]struct{}{"Hello": struct{}{}, "World": struct{}{}})) + }) + It("should SMove", func() { sAdd := client.SAdd("set1", "one") Expect(sAdd.Err()).NotTo(HaveOccurred()) diff --git a/vendor/github.com/go-redis/redis/example_test.go b/vendor/github.com/go-redis/redis/example_test.go index 7e04cd487..4d18ddb94 100644 --- a/vendor/github.com/go-redis/redis/example_test.go +++ b/vendor/github.com/go-redis/redis/example_test.go @@ -96,14 +96,14 @@ func ExampleClient() { val2, err := client.Get("key2").Result() if err == redis.Nil { - fmt.Println("key2 does not exists") + fmt.Println("key2 does not exist") } else if err != nil { panic(err) } else { fmt.Println("key2", val2) } // Output: key value - // key2 does not exists + // key2 does not exist } func ExampleClient_Set() { diff --git a/vendor/github.com/go-redis/redis/internal/hashtag/hashtag.go b/vendor/github.com/go-redis/redis/internal/hashtag/hashtag.go index 2866488e5..8c7ebbfa6 100644 --- a/vendor/github.com/go-redis/redis/internal/hashtag/hashtag.go +++ b/vendor/github.com/go-redis/redis/internal/hashtag/hashtag.go @@ -55,13 +55,17 @@ func Key(key string) string { return key } +func RandomSlot() int { + return rand.Intn(SlotNumber) +} + // hashSlot returns a consistent slot number between 0 and 16383 // for any given string key. func Slot(key string) int { - key = Key(key) if key == "" { - return rand.Intn(SlotNumber) + return RandomSlot() } + key = Key(key) return int(crc16sum(key)) % SlotNumber } diff --git a/vendor/github.com/go-redis/redis/internal/proto/scan.go b/vendor/github.com/go-redis/redis/internal/proto/scan.go index 03c8b59aa..0329ffd99 100644 --- a/vendor/github.com/go-redis/redis/internal/proto/scan.go +++ b/vendor/github.com/go-redis/redis/internal/proto/scan.go @@ -123,8 +123,9 @@ func ScanSlice(data []string, slice interface{}) error { next := internal.MakeSliceNextElemFunc(v) for i, s := range data { elem := next() - if err := Scan(internal.StringToBytes(s), elem.Addr().Interface()); err != nil { - return fmt.Errorf("redis: ScanSlice(index=%d value=%q) failed: %s", i, s, err) + if err := Scan([]byte(s), elem.Addr().Interface()); err != nil { + err = fmt.Errorf("redis: ScanSlice index=%d value=%q failed: %s", i, s, err) + return err } } diff --git a/vendor/github.com/go-redis/redis/internal/safe.go b/vendor/github.com/go-redis/redis/internal/safe.go index 870fe541f..dc5f4cc8a 100644 --- a/vendor/github.com/go-redis/redis/internal/safe.go +++ b/vendor/github.com/go-redis/redis/internal/safe.go @@ -5,7 +5,3 @@ package internal func BytesToString(b []byte) string { return string(b) } - -func StringToBytes(s string) []byte { - return []byte(s) -} diff --git a/vendor/github.com/go-redis/redis/internal/unsafe.go b/vendor/github.com/go-redis/redis/internal/unsafe.go index c18b25c17..3ae48c14b 100644 --- a/vendor/github.com/go-redis/redis/internal/unsafe.go +++ b/vendor/github.com/go-redis/redis/internal/unsafe.go @@ -3,25 +3,10 @@ package internal import ( - "reflect" "unsafe" ) +// BytesToString converts byte slice to string. func BytesToString(b []byte) string { - bytesHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b)) - strHeader := reflect.StringHeader{ - Data: bytesHeader.Data, - Len: bytesHeader.Len, - } - return *(*string)(unsafe.Pointer(&strHeader)) -} - -func StringToBytes(s string) []byte { - sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) - bh := reflect.SliceHeader{ - Data: sh.Data, - Len: sh.Len, - Cap: sh.Len, - } - return *(*[]byte)(unsafe.Pointer(&bh)) + return *(*string)(unsafe.Pointer(&b)) } diff --git a/vendor/github.com/go-redis/redis/options_test.go b/vendor/github.com/go-redis/redis/options_test.go index 6a4af7169..211f6b195 100644 --- a/vendor/github.com/go-redis/redis/options_test.go +++ b/vendor/github.com/go-redis/redis/options_test.go @@ -71,7 +71,7 @@ func TestParseURL(t *testing.T) { t.Run(c.u, func(t *testing.T) { o, err := ParseURL(c.u) if c.err == nil && err != nil { - t.Fatalf("unexpected error: '%q'", err) + t.Fatalf("unexpected error: %q", err) return } if c.err != nil && err != nil { diff --git a/vendor/github.com/go-redis/redis/parser.go b/vendor/github.com/go-redis/redis/parser.go index 1d7ec630e..b378abc4e 100644 --- a/vendor/github.com/go-redis/redis/parser.go +++ b/vendor/github.com/go-redis/redis/parser.go @@ -98,6 +98,20 @@ func stringIntMapParser(rd *proto.Reader, n int64) (interface{}, error) { } // Implements proto.MultiBulkParse +func stringStructMapParser(rd *proto.Reader, n int64) (interface{}, error) { + m := make(map[string]struct{}, n) + for i := int64(0); i < n; i++ { + key, err := rd.ReadStringReply() + if err != nil { + return nil, err + } + + m[key] = struct{}{} + } + return m, nil +} + +// Implements proto.MultiBulkParse func zSliceParser(rd *proto.Reader, n int64) (interface{}, error) { zz := make([]Z, n/2) for i := int64(0); i < n; i += 2 { diff --git a/vendor/github.com/go-redis/redis/redis.go b/vendor/github.com/go-redis/redis/redis.go index 230091b3e..37ffafd97 100644 --- a/vendor/github.com/go-redis/redis/redis.go +++ b/vendor/github.com/go-redis/redis/redis.go @@ -11,7 +11,7 @@ import ( "github.com/go-redis/redis/internal/proto" ) -// Redis nil reply, .e.g. when key does not exist. +// Redis nil reply returned when key does not exist. const Nil = internal.Nil func init() { diff --git a/vendor/github.com/go-redis/redis/ring.go b/vendor/github.com/go-redis/redis/ring.go index a30c32102..c11ef6bc2 100644 --- a/vendor/github.com/go-redis/redis/ring.go +++ b/vendor/github.com/go-redis/redis/ring.go @@ -298,6 +298,9 @@ func (c *Ring) cmdInfo(name string) *CommandInfo { if err != nil { return nil } + if c.cmdsInfo == nil { + return nil + } info := c.cmdsInfo[name] if info == nil { internal.Logf("info for cmd=%s not found", name) @@ -343,7 +346,11 @@ func (c *Ring) shardByName(name string) (*ringShard, error) { func (c *Ring) cmdShard(cmd Cmder) (*ringShard, error) { cmdInfo := c.cmdInfo(cmd.Name()) - firstKey := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo)) + pos := cmdFirstKeyPos(cmd, cmdInfo) + if pos == 0 { + return c.randomShard() + } + firstKey := cmd.stringArg(pos) return c.shardByKey(firstKey) } diff --git a/vendor/github.com/go-redis/redis/universal.go b/vendor/github.com/go-redis/redis/universal.go index 29eb12b18..ea42f6984 100644 --- a/vendor/github.com/go-redis/redis/universal.go +++ b/vendor/github.com/go-redis/redis/universal.go @@ -114,6 +114,8 @@ func (o *UniversalOptions) simple() *Options { type UniversalClient interface { Cmdable Process(cmd Cmder) error + Subscribe(channels ...string) *PubSub + PSubscribe(channels ...string) *PubSub Close() error } |