summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/go-redis/redis
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/go-redis/redis')
-rw-r--r--vendor/github.com/go-redis/redis/.travis.yml2
-rw-r--r--vendor/github.com/go-redis/redis/README.md5
-rw-r--r--vendor/github.com/go-redis/redis/cluster.go76
-rw-r--r--vendor/github.com/go-redis/redis/cluster_test.go26
-rw-r--r--vendor/github.com/go-redis/redis/command.go42
-rw-r--r--vendor/github.com/go-redis/redis/commands.go10
-rw-r--r--vendor/github.com/go-redis/redis/commands_test.go11
-rw-r--r--vendor/github.com/go-redis/redis/example_test.go4
-rw-r--r--vendor/github.com/go-redis/redis/internal/hashtag/hashtag.go8
-rw-r--r--vendor/github.com/go-redis/redis/internal/proto/scan.go5
-rw-r--r--vendor/github.com/go-redis/redis/internal/safe.go4
-rw-r--r--vendor/github.com/go-redis/redis/internal/unsafe.go19
-rw-r--r--vendor/github.com/go-redis/redis/options_test.go2
-rw-r--r--vendor/github.com/go-redis/redis/parser.go14
-rw-r--r--vendor/github.com/go-redis/redis/redis.go2
-rw-r--r--vendor/github.com/go-redis/redis/ring.go9
-rw-r--r--vendor/github.com/go-redis/redis/universal.go2
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
}