summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/go-redis
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2018-04-16 05:37:14 -0700
committerJoram Wilander <jwawilander@gmail.com>2018-04-16 08:37:14 -0400
commit6e2cb00008cbf09e556b00f87603797fcaa47e09 (patch)
tree3c0eb55ff4226a3f024aad373140d1fb860a6404 /vendor/github.com/go-redis
parentbf24f51c4e1cc6286885460672f7f449e8c6f5ef (diff)
downloadchat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.gz
chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.bz2
chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.zip
Depenancy upgrades and movign to dep. (#8630)
Diffstat (limited to 'vendor/github.com/go-redis')
-rw-r--r--vendor/github.com/go-redis/redis/.travis.yml1
-rw-r--r--vendor/github.com/go-redis/redis/Makefile3
-rw-r--r--vendor/github.com/go-redis/redis/bench_test.go216
-rw-r--r--vendor/github.com/go-redis/redis/cluster.go547
-rw-r--r--vendor/github.com/go-redis/redis/cluster_test.go813
-rw-r--r--vendor/github.com/go-redis/redis/command.go26
-rw-r--r--vendor/github.com/go-redis/redis/command_test.go60
-rw-r--r--vendor/github.com/go-redis/redis/commands.go146
-rw-r--r--vendor/github.com/go-redis/redis/commands_test.go2968
-rw-r--r--vendor/github.com/go-redis/redis/example_instrumentation_test.go48
-rw-r--r--vendor/github.com/go-redis/redis/example_test.go414
-rw-r--r--vendor/github.com/go-redis/redis/export_test.go46
-rw-r--r--vendor/github.com/go-redis/redis/internal/consistenthash/consistenthash_test.go110
-rw-r--r--vendor/github.com/go-redis/redis/internal/error.go14
-rw-r--r--vendor/github.com/go-redis/redis/internal/hashtag/hashtag_test.go74
-rw-r--r--vendor/github.com/go-redis/redis/internal/internal_test.go18
-rw-r--r--vendor/github.com/go-redis/redis/internal/pool/bench_test.go80
-rw-r--r--vendor/github.com/go-redis/redis/internal/pool/main_test.go35
-rw-r--r--vendor/github.com/go-redis/redis/internal/pool/pool_test.go241
-rw-r--r--vendor/github.com/go-redis/redis/internal/proto/proto_test.go13
-rw-r--r--vendor/github.com/go-redis/redis/internal/proto/reader.go48
-rw-r--r--vendor/github.com/go-redis/redis/internal/proto/reader_test.go87
-rw-r--r--vendor/github.com/go-redis/redis/internal/proto/scan.go63
-rw-r--r--vendor/github.com/go-redis/redis/internal/proto/scan_test.go48
-rw-r--r--vendor/github.com/go-redis/redis/internal/proto/write_buffer.go18
-rw-r--r--vendor/github.com/go-redis/redis/internal/proto/write_buffer_test.go63
-rw-r--r--vendor/github.com/go-redis/redis/internal/singleflight/singleflight.go64
-rw-r--r--vendor/github.com/go-redis/redis/internal/util.go37
-rw-r--r--vendor/github.com/go-redis/redis/internal/util/safe.go (renamed from vendor/github.com/go-redis/redis/internal/safe.go)2
-rw-r--r--vendor/github.com/go-redis/redis/internal/util/strconv.go19
-rw-r--r--vendor/github.com/go-redis/redis/internal/util/unsafe.go (renamed from vendor/github.com/go-redis/redis/internal/unsafe.go)2
-rw-r--r--vendor/github.com/go-redis/redis/iterator_test.go136
-rw-r--r--vendor/github.com/go-redis/redis/main_test.go351
-rw-r--r--vendor/github.com/go-redis/redis/options_test.go94
-rw-r--r--vendor/github.com/go-redis/redis/parser.go26
-rw-r--r--vendor/github.com/go-redis/redis/pipeline_test.go80
-rw-r--r--vendor/github.com/go-redis/redis/pool_test.go143
-rw-r--r--vendor/github.com/go-redis/redis/pubsub.go70
-rw-r--r--vendor/github.com/go-redis/redis/pubsub_test.go443
-rw-r--r--vendor/github.com/go-redis/redis/race_test.go250
-rw-r--r--vendor/github.com/go-redis/redis/redis.go85
-rw-r--r--vendor/github.com/go-redis/redis/redis_context.go38
-rw-r--r--vendor/github.com/go-redis/redis/redis_no_context.go18
-rw-r--r--vendor/github.com/go-redis/redis/redis_test.go364
-rw-r--r--vendor/github.com/go-redis/redis/ring.go370
-rw-r--r--vendor/github.com/go-redis/redis/ring_test.go193
-rw-r--r--vendor/github.com/go-redis/redis/script.go4
-rw-r--r--vendor/github.com/go-redis/redis/sentinel_test.go88
-rw-r--r--vendor/github.com/go-redis/redis/testdata/redis.conf10
-rw-r--r--vendor/github.com/go-redis/redis/tx.go4
-rw-r--r--vendor/github.com/go-redis/redis/tx_test.go151
-rw-r--r--vendor/github.com/go-redis/redis/universal.go1
-rw-r--r--vendor/github.com/go-redis/redis/universal_test.go41
53 files changed, 940 insertions, 8344 deletions
diff --git a/vendor/github.com/go-redis/redis/.travis.yml b/vendor/github.com/go-redis/redis/.travis.yml
index c95b3e6c6..39ffc2bec 100644
--- a/vendor/github.com/go-redis/redis/.travis.yml
+++ b/vendor/github.com/go-redis/redis/.travis.yml
@@ -8,6 +8,7 @@ go:
- 1.7.x
- 1.8.x
- 1.9.x
+ - 1.10.x
- tip
matrix:
diff --git a/vendor/github.com/go-redis/redis/Makefile b/vendor/github.com/go-redis/redis/Makefile
index 50fdc55a1..1fbdac91c 100644
--- a/vendor/github.com/go-redis/redis/Makefile
+++ b/vendor/github.com/go-redis/redis/Makefile
@@ -1,6 +1,7 @@
all: testdeps
go test ./...
go test ./... -short -race
+ env GOOS=linux GOARCH=386 go test ./...
go vet
testdeps: testdata/redis/src/redis-server
@@ -15,5 +16,5 @@ testdata/redis:
wget -qO- https://github.com/antirez/redis/archive/unstable.tar.gz | tar xvz --strip-components=1 -C $@
testdata/redis/src/redis-server: testdata/redis
- sed -i 's/libjemalloc.a/libjemalloc.a -lrt/g' $</src/Makefile
+ sed -i.bak 's/libjemalloc.a/libjemalloc.a -lrt/g' $</src/Makefile
cd $< && make all
diff --git a/vendor/github.com/go-redis/redis/bench_test.go b/vendor/github.com/go-redis/redis/bench_test.go
deleted file mode 100644
index f6b75c72a..000000000
--- a/vendor/github.com/go-redis/redis/bench_test.go
+++ /dev/null
@@ -1,216 +0,0 @@
-package redis_test
-
-import (
- "bytes"
- "testing"
- "time"
-
- "github.com/go-redis/redis"
-)
-
-func benchmarkRedisClient(poolSize int) *redis.Client {
- client := redis.NewClient(&redis.Options{
- Addr: ":6379",
- DialTimeout: time.Second,
- ReadTimeout: time.Second,
- WriteTimeout: time.Second,
- PoolSize: poolSize,
- })
- if err := client.FlushDB().Err(); err != nil {
- panic(err)
- }
- return client
-}
-
-func BenchmarkRedisPing(b *testing.B) {
- client := benchmarkRedisClient(10)
- defer client.Close()
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- if err := client.Ping().Err(); err != nil {
- b.Fatal(err)
- }
- }
- })
-}
-
-func BenchmarkRedisSetString(b *testing.B) {
- client := benchmarkRedisClient(10)
- defer client.Close()
-
- value := string(bytes.Repeat([]byte{'1'}, 10000))
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- if err := client.Set("key", value, 0).Err(); err != nil {
- b.Fatal(err)
- }
- }
- })
-}
-
-func BenchmarkRedisGetNil(b *testing.B) {
- client := benchmarkRedisClient(10)
- defer client.Close()
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- if err := client.Get("key").Err(); err != redis.Nil {
- b.Fatal(err)
- }
- }
- })
-}
-
-func benchmarkSetRedis(b *testing.B, poolSize, payloadSize int) {
- client := benchmarkRedisClient(poolSize)
- defer client.Close()
-
- value := string(bytes.Repeat([]byte{'1'}, payloadSize))
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- if err := client.Set("key", value, 0).Err(); err != nil {
- b.Fatal(err)
- }
- }
- })
-}
-
-func BenchmarkSetRedis10Conns64Bytes(b *testing.B) {
- benchmarkSetRedis(b, 10, 64)
-}
-
-func BenchmarkSetRedis100Conns64Bytes(b *testing.B) {
- benchmarkSetRedis(b, 100, 64)
-}
-
-func BenchmarkSetRedis10Conns1KB(b *testing.B) {
- benchmarkSetRedis(b, 10, 1024)
-}
-
-func BenchmarkSetRedis100Conns1KB(b *testing.B) {
- benchmarkSetRedis(b, 100, 1024)
-}
-
-func BenchmarkSetRedis10Conns10KB(b *testing.B) {
- benchmarkSetRedis(b, 10, 10*1024)
-}
-
-func BenchmarkSetRedis100Conns10KB(b *testing.B) {
- benchmarkSetRedis(b, 100, 10*1024)
-}
-
-func BenchmarkSetRedis10Conns1MB(b *testing.B) {
- benchmarkSetRedis(b, 10, 1024*1024)
-}
-
-func BenchmarkSetRedis100Conns1MB(b *testing.B) {
- benchmarkSetRedis(b, 100, 1024*1024)
-}
-
-func BenchmarkRedisSetGetBytes(b *testing.B) {
- client := benchmarkRedisClient(10)
- defer client.Close()
-
- value := bytes.Repeat([]byte{'1'}, 10000)
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- if err := client.Set("key", value, 0).Err(); err != nil {
- b.Fatal(err)
- }
-
- got, err := client.Get("key").Bytes()
- if err != nil {
- b.Fatal(err)
- }
- if !bytes.Equal(got, value) {
- b.Fatalf("got != value")
- }
- }
- })
-}
-
-func BenchmarkRedisMGet(b *testing.B) {
- client := benchmarkRedisClient(10)
- defer client.Close()
-
- if err := client.MSet("key1", "hello1", "key2", "hello2").Err(); err != nil {
- b.Fatal(err)
- }
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- if err := client.MGet("key1", "key2").Err(); err != nil {
- b.Fatal(err)
- }
- }
- })
-}
-
-func BenchmarkSetExpire(b *testing.B) {
- client := benchmarkRedisClient(10)
- defer client.Close()
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- if err := client.Set("key", "hello", 0).Err(); err != nil {
- b.Fatal(err)
- }
- if err := client.Expire("key", time.Second).Err(); err != nil {
- b.Fatal(err)
- }
- }
- })
-}
-
-func BenchmarkPipeline(b *testing.B) {
- client := benchmarkRedisClient(10)
- defer client.Close()
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- _, err := client.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Set("key", "hello", 0)
- pipe.Expire("key", time.Second)
- return nil
- })
- if err != nil {
- b.Fatal(err)
- }
- }
- })
-}
-
-func BenchmarkZAdd(b *testing.B) {
- client := benchmarkRedisClient(10)
- defer client.Close()
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- if err := client.ZAdd("key", redis.Z{float64(1), "hello"}).Err(); err != nil {
- b.Fatal(err)
- }
- }
- })
-}
diff --git a/vendor/github.com/go-redis/redis/cluster.go b/vendor/github.com/go-redis/redis/cluster.go
index a2c18b387..4a2951157 100644
--- a/vendor/github.com/go-redis/redis/cluster.go
+++ b/vendor/github.com/go-redis/redis/cluster.go
@@ -1,7 +1,10 @@
package redis
import (
+ "context"
+ "errors"
"fmt"
+ "math"
"math/rand"
"net"
"sync"
@@ -12,10 +15,10 @@ import (
"github.com/go-redis/redis/internal/hashtag"
"github.com/go-redis/redis/internal/pool"
"github.com/go-redis/redis/internal/proto"
+ "github.com/go-redis/redis/internal/singleflight"
)
var errClusterNoNodes = fmt.Errorf("redis: cluster has no nodes")
-var errNilClusterState = fmt.Errorf("redis: cannot load cluster slots")
// ClusterOptions are used to configure a cluster client and should be
// passed to NewClusterClient.
@@ -25,13 +28,15 @@ type ClusterOptions struct {
// The maximum number of retries before giving up. Command is retried
// on network errors and MOVED/ASK redirects.
- // Default is 16.
+ // Default is 8.
MaxRedirects int
// Enables read-only commands on slave nodes.
ReadOnly bool
// Allows routing read-only commands to the closest master or slave node.
RouteByLatency bool
+ // Allows routing read-only commands to the random master or slave node.
+ RouteRandomly bool
// Following options are copied from Options struct.
@@ -57,7 +62,7 @@ func (opt *ClusterOptions) init() {
if opt.MaxRedirects == -1 {
opt.MaxRedirects = 0
} else if opt.MaxRedirects == 0 {
- opt.MaxRedirects = 16
+ opt.MaxRedirects = 8
}
if opt.RouteByLatency {
@@ -118,11 +123,11 @@ func (opt *ClusterOptions) clientOptions() *Options {
//------------------------------------------------------------------------------
type clusterNode struct {
- Client *Client
- Latency time.Duration
+ Client *Client
- loading time.Time
- generation uint32
+ latency uint32 // atomic
+ generation uint32 // atomic
+ loading uint32 // atomic
}
func newClusterNode(clOpt *ClusterOptions, addr string) *clusterNode {
@@ -132,36 +137,69 @@ func newClusterNode(clOpt *ClusterOptions, addr string) *clusterNode {
Client: NewClient(opt),
}
+ node.latency = math.MaxUint32
if clOpt.RouteByLatency {
- node.updateLatency()
+ go node.updateLatency()
}
return &node
}
+func (n *clusterNode) Close() error {
+ return n.Client.Close()
+}
+
+func (n *clusterNode) Test() error {
+ return n.Client.ClusterInfo().Err()
+}
+
func (n *clusterNode) updateLatency() {
const probes = 10
+
+ var latency uint32
for i := 0; i < probes; i++ {
start := time.Now()
n.Client.Ping()
- n.Latency += time.Since(start)
+ probe := uint32(time.Since(start) / time.Microsecond)
+ latency = (latency + probe) / 2
}
- n.Latency = n.Latency / probes
+ atomic.StoreUint32(&n.latency, latency)
+}
+
+func (n *clusterNode) Latency() time.Duration {
+ latency := atomic.LoadUint32(&n.latency)
+ return time.Duration(latency) * time.Microsecond
+}
+
+func (n *clusterNode) MarkAsLoading() {
+ atomic.StoreUint32(&n.loading, uint32(time.Now().Unix()))
}
func (n *clusterNode) Loading() bool {
- return !n.loading.IsZero() && time.Since(n.loading) < time.Minute
+ const minute = int64(time.Minute / time.Second)
+
+ loading := atomic.LoadUint32(&n.loading)
+ if loading == 0 {
+ return false
+ }
+ if time.Now().Unix()-int64(loading) < minute {
+ return true
+ }
+ atomic.StoreUint32(&n.loading, 0)
+ return false
}
func (n *clusterNode) Generation() uint32 {
- return n.generation
+ return atomic.LoadUint32(&n.generation)
}
func (n *clusterNode) SetGeneration(gen uint32) {
- if gen < n.generation {
- panic("gen < n.generation")
+ for {
+ v := atomic.LoadUint32(&n.generation)
+ if gen < v || atomic.CompareAndSwapUint32(&n.generation, v, gen) {
+ break
+ }
}
- n.generation = gen
}
//------------------------------------------------------------------------------
@@ -169,18 +207,23 @@ func (n *clusterNode) SetGeneration(gen uint32) {
type clusterNodes struct {
opt *ClusterOptions
- mu sync.RWMutex
- addrs []string
- nodes map[string]*clusterNode
- closed bool
+ mu sync.RWMutex
+ allAddrs []string
+ allNodes map[string]*clusterNode
+ clusterAddrs []string
+ closed bool
+
+ nodeCreateGroup singleflight.Group
generation uint32
}
func newClusterNodes(opt *ClusterOptions) *clusterNodes {
return &clusterNodes{
- opt: opt,
- nodes: make(map[string]*clusterNode),
+ opt: opt,
+
+ allAddrs: opt.Addrs,
+ allNodes: make(map[string]*clusterNode),
}
}
@@ -194,21 +237,29 @@ func (c *clusterNodes) Close() error {
c.closed = true
var firstErr error
- for _, node := range c.nodes {
+ for _, node := range c.allNodes {
if err := node.Client.Close(); err != nil && firstErr == nil {
firstErr = err
}
}
- c.addrs = nil
- c.nodes = nil
+
+ c.allNodes = nil
+ c.clusterAddrs = nil
return firstErr
}
func (c *clusterNodes) Addrs() ([]string, error) {
+ var addrs []string
c.mu.RLock()
closed := c.closed
- addrs := c.addrs
+ if !closed {
+ if len(c.clusterAddrs) > 0 {
+ addrs = c.clusterAddrs
+ } else {
+ addrs = c.allAddrs
+ }
+ }
c.mu.RUnlock()
if closed {
@@ -229,55 +280,45 @@ func (c *clusterNodes) NextGeneration() uint32 {
func (c *clusterNodes) GC(generation uint32) {
var collected []*clusterNode
c.mu.Lock()
- for i := 0; i < len(c.addrs); {
- addr := c.addrs[i]
- node := c.nodes[addr]
+ for addr, node := range c.allNodes {
if node.Generation() >= generation {
- i++
continue
}
- c.addrs = append(c.addrs[:i], c.addrs[i+1:]...)
- delete(c.nodes, addr)
+ c.clusterAddrs = remove(c.clusterAddrs, addr)
+ delete(c.allNodes, addr)
collected = append(collected, node)
}
c.mu.Unlock()
- time.AfterFunc(time.Minute, func() {
- for _, node := range collected {
- _ = node.Client.Close()
- }
- })
-}
-
-func (c *clusterNodes) All() ([]*clusterNode, error) {
- c.mu.RLock()
- defer c.mu.RUnlock()
-
- if c.closed {
- return nil, pool.ErrClosed
+ for _, node := range collected {
+ _ = node.Client.Close()
}
-
- nodes := make([]*clusterNode, 0, len(c.nodes))
- for _, node := range c.nodes {
- nodes = append(nodes, node)
- }
- return nodes, nil
}
func (c *clusterNodes) GetOrCreate(addr string) (*clusterNode, error) {
var node *clusterNode
- var ok bool
+ var err error
c.mu.RLock()
- if !c.closed {
- node, ok = c.nodes[addr]
+ if c.closed {
+ err = pool.ErrClosed
+ } else {
+ node = c.allNodes[addr]
}
c.mu.RUnlock()
- if ok {
+ if err != nil {
+ return nil, err
+ }
+ if node != nil {
return node, nil
}
+ v, err := c.nodeCreateGroup.Do(addr, func() (interface{}, error) {
+ node := newClusterNode(c.opt, addr)
+ return node, node.Test()
+ })
+
c.mu.Lock()
defer c.mu.Unlock()
@@ -285,15 +326,35 @@ func (c *clusterNodes) GetOrCreate(addr string) (*clusterNode, error) {
return nil, pool.ErrClosed
}
- node, ok = c.nodes[addr]
+ node, ok := c.allNodes[addr]
if ok {
- return node, nil
+ _ = v.(*clusterNode).Close()
+ return node, err
}
+ node = v.(*clusterNode)
- c.addrs = append(c.addrs, addr)
- node = newClusterNode(c.opt, addr)
- c.nodes[addr] = node
- return node, nil
+ c.allAddrs = appendIfNotExists(c.allAddrs, addr)
+ if err == nil {
+ c.clusterAddrs = append(c.clusterAddrs, addr)
+ }
+ c.allNodes[addr] = node
+
+ return node, err
+}
+
+func (c *clusterNodes) All() ([]*clusterNode, error) {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+
+ if c.closed {
+ return nil, pool.ErrClosed
+ }
+
+ cp := make([]*clusterNode, 0, len(c.allNodes))
+ for _, node := range c.allNodes {
+ cp = append(cp, node)
+ }
+ return cp, nil
}
func (c *clusterNodes) Random() (*clusterNode, error) {
@@ -302,20 +363,8 @@ func (c *clusterNodes) Random() (*clusterNode, error) {
return nil, err
}
- var nodeErr error
- for i := 0; i <= c.opt.MaxRedirects; i++ {
- n := rand.Intn(len(addrs))
- node, err := c.GetOrCreate(addrs[n])
- if err != nil {
- return nil, err
- }
-
- nodeErr = node.Client.ClusterInfo().Err()
- if nodeErr == nil {
- return node, nil
- }
- }
- return nil, nodeErr
+ n := rand.Intn(len(addrs))
+ return c.GetOrCreate(addrs[n])
}
//------------------------------------------------------------------------------
@@ -367,6 +416,10 @@ func newClusterState(nodes *clusterNodes, slots []ClusterSlot, origin string) (*
}
}
+ time.AfterFunc(time.Minute, func() {
+ nodes.GC(c.generation)
+ })
+
return &c, nil
}
@@ -416,13 +469,19 @@ func (c *clusterState) slotClosestNode(slot int) (*clusterNode, error) {
if n.Loading() {
continue
}
- if node == nil || node.Latency-n.Latency > threshold {
+ if node == nil || node.Latency()-n.Latency() > threshold {
node = n
}
}
return node, nil
}
+func (c *clusterState) slotRandomNode(slot int) *clusterNode {
+ nodes := c.slotNodes(slot)
+ n := rand.Intn(len(nodes))
+ return nodes[n]
+}
+
func (c *clusterState) slotNodes(slot int) []*clusterNode {
if slot >= 0 && slot < len(c.slots) {
return c.slots[slot]
@@ -432,25 +491,83 @@ func (c *clusterState) slotNodes(slot int) []*clusterNode {
//------------------------------------------------------------------------------
+type clusterStateHolder struct {
+ load func() (*clusterState, error)
+
+ state atomic.Value
+
+ lastErrMu sync.RWMutex
+ lastErr error
+
+ reloading uint32 // atomic
+}
+
+func newClusterStateHolder(fn func() (*clusterState, error)) *clusterStateHolder {
+ return &clusterStateHolder{
+ load: fn,
+ }
+}
+
+func (c *clusterStateHolder) Load() (*clusterState, error) {
+ state, err := c.load()
+ if err != nil {
+ c.lastErrMu.Lock()
+ c.lastErr = err
+ c.lastErrMu.Unlock()
+ return nil, err
+ }
+ c.state.Store(state)
+ return state, nil
+}
+
+func (c *clusterStateHolder) LazyReload() {
+ if !atomic.CompareAndSwapUint32(&c.reloading, 0, 1) {
+ return
+ }
+ go func() {
+ defer atomic.StoreUint32(&c.reloading, 0)
+
+ _, err := c.Load()
+ if err == nil {
+ time.Sleep(time.Second)
+ }
+ }()
+}
+
+func (c *clusterStateHolder) Get() (*clusterState, error) {
+ v := c.state.Load()
+ if v != nil {
+ return v.(*clusterState), nil
+ }
+
+ c.lastErrMu.RLock()
+ err := c.lastErr
+ c.lastErrMu.RUnlock()
+ if err != nil {
+ return nil, err
+ }
+
+ return nil, errors.New("redis: cluster has no state")
+}
+
+//------------------------------------------------------------------------------
+
// ClusterClient is a Redis Cluster client representing a pool of zero
// or more underlying connections. It's safe for concurrent use by
// multiple goroutines.
type ClusterClient struct {
cmdable
- opt *ClusterOptions
- nodes *clusterNodes
- _state atomic.Value
+ ctx context.Context
- cmdsInfoOnce internal.Once
- cmdsInfo map[string]*CommandInfo
+ opt *ClusterOptions
+ nodes *clusterNodes
+ state *clusterStateHolder
+ cmdsInfoCache *cmdsInfoCache
process func(Cmder) error
processPipeline func([]Cmder) error
processTxPipeline func([]Cmder) error
-
- // Reports whether slots reloading is in progress.
- reloading uint32
}
// NewClusterClient returns a Redis Cluster client as described in
@@ -459,9 +576,11 @@ func NewClusterClient(opt *ClusterOptions) *ClusterClient {
opt.init()
c := &ClusterClient{
- opt: opt,
- nodes: newClusterNodes(opt),
+ opt: opt,
+ nodes: newClusterNodes(opt),
+ cmdsInfoCache: newCmdsInfoCache(),
}
+ c.state = newClusterStateHolder(c.loadState)
c.process = c.defaultProcess
c.processPipeline = c.defaultProcessPipeline
@@ -469,25 +588,33 @@ func NewClusterClient(opt *ClusterOptions) *ClusterClient {
c.cmdable.setProcessor(c.Process)
- // Add initial nodes.
- for _, addr := range opt.Addrs {
- _, _ = c.nodes.GetOrCreate(addr)
+ _, _ = c.state.Load()
+ if opt.IdleCheckFrequency > 0 {
+ go c.reaper(opt.IdleCheckFrequency)
}
- // Preload cluster slots.
- for i := 0; i < 10; i++ {
- state, err := c.reloadState()
- if err == nil {
- c._state.Store(state)
- break
- }
+ return c
+}
+
+func (c *ClusterClient) Context() context.Context {
+ if c.ctx != nil {
+ return c.ctx
}
+ return context.Background()
+}
- if opt.IdleCheckFrequency > 0 {
- go c.reaper(opt.IdleCheckFrequency)
+func (c *ClusterClient) WithContext(ctx context.Context) *ClusterClient {
+ if ctx == nil {
+ panic("nil context")
}
+ c2 := c.copy()
+ c2.ctx = ctx
+ return c2
+}
- return c
+func (c *ClusterClient) copy() *ClusterClient {
+ cp := *c
+ return &cp
}
// Options returns read-only Options that were used to create the client.
@@ -499,40 +626,18 @@ func (c *ClusterClient) retryBackoff(attempt int) time.Duration {
return internal.RetryBackoff(attempt, c.opt.MinRetryBackoff, c.opt.MaxRetryBackoff)
}
-func (c *ClusterClient) state() (*clusterState, error) {
- v := c._state.Load()
- if v != nil {
- return v.(*clusterState), nil
- }
-
- _, err := c.nodes.Addrs()
- if err != nil {
- return nil, err
- }
-
- c.lazyReloadState()
- return nil, errNilClusterState
-}
-
func (c *ClusterClient) cmdInfo(name string) *CommandInfo {
- err := c.cmdsInfoOnce.Do(func() error {
+ cmdsInfo, err := c.cmdsInfoCache.Do(func() (map[string]*CommandInfo, error) {
node, err := c.nodes.Random()
if err != nil {
- return err
- }
-
- cmdsInfo, err := node.Client.Command().Result()
- if err != nil {
- return err
+ return nil, err
}
-
- c.cmdsInfo = cmdsInfo
- return nil
+ return node.Client.Command().Result()
})
if err != nil {
return nil
}
- info := c.cmdsInfo[name]
+ info := cmdsInfo[name]
if info == nil {
internal.Logf("info for cmd=%s not found", name)
}
@@ -552,7 +657,12 @@ func (c *ClusterClient) cmdSlot(cmd Cmder) int {
return cmdSlot(cmd, cmdFirstKeyPos(cmd, cmdInfo))
}
-func (c *ClusterClient) cmdSlotAndNode(state *clusterState, cmd Cmder) (int, *clusterNode, error) {
+func (c *ClusterClient) cmdSlotAndNode(cmd Cmder) (int, *clusterNode, error) {
+ state, err := c.state.Get()
+ if err != nil {
+ return 0, nil, err
+ }
+
cmdInfo := c.cmdInfo(cmd.Name())
slot := cmdSlot(cmd, cmdFirstKeyPos(cmd, cmdInfo))
@@ -562,6 +672,11 @@ func (c *ClusterClient) cmdSlotAndNode(state *clusterState, cmd Cmder) (int, *cl
return slot, node, err
}
+ if c.opt.RouteRandomly {
+ node := state.slotRandomNode(slot)
+ return slot, node, nil
+ }
+
node, err := state.slotSlaveNode(slot)
return slot, node, err
}
@@ -570,16 +685,24 @@ func (c *ClusterClient) cmdSlotAndNode(state *clusterState, cmd Cmder) (int, *cl
return slot, node, err
}
+func (c *ClusterClient) slotMasterNode(slot int) (*clusterNode, error) {
+ state, err := c.state.Get()
+ if err != nil {
+ return nil, err
+ }
+
+ nodes := state.slotNodes(slot)
+ if len(nodes) > 0 {
+ return nodes[0], nil
+ }
+ return c.nodes.Random()
+}
+
func (c *ClusterClient) Watch(fn func(*Tx) error, keys ...string) error {
if len(keys) == 0 {
return fmt.Errorf("redis: keys don't hash to the same slot")
}
- state, err := c.state()
- if err != nil {
- return err
- }
-
slot := hashtag.Slot(keys[0])
for _, key := range keys[1:] {
if hashtag.Slot(key) != slot {
@@ -587,7 +710,7 @@ func (c *ClusterClient) Watch(fn func(*Tx) error, keys ...string) error {
}
}
- node, err := state.slotMasterNode(slot)
+ node, err := c.slotMasterNode(slot)
if err != nil {
return err
}
@@ -608,7 +731,7 @@ func (c *ClusterClient) Watch(fn func(*Tx) error, keys ...string) error {
moved, ask, addr := internal.IsMovedError(err)
if moved || ask {
- c.lazyReloadState()
+ c.state.LazyReload()
node, err = c.nodes.GetOrCreate(addr)
if err != nil {
return err
@@ -617,10 +740,11 @@ func (c *ClusterClient) Watch(fn func(*Tx) error, keys ...string) error {
}
if err == pool.ErrClosed {
- node, err = state.slotMasterNode(slot)
+ node, err = c.slotMasterNode(slot)
if err != nil {
return err
}
+ continue
}
return err
@@ -644,31 +768,27 @@ func (c *ClusterClient) WrapProcess(
}
func (c *ClusterClient) Process(cmd Cmder) error {
- if c.process != nil {
- return c.process(cmd)
- }
- return c.defaultProcess(cmd)
+ return c.process(cmd)
}
func (c *ClusterClient) defaultProcess(cmd Cmder) error {
- state, err := c.state()
- if err != nil {
- cmd.setErr(err)
- return err
- }
-
- _, node, err := c.cmdSlotAndNode(state, cmd)
- if err != nil {
- cmd.setErr(err)
- return err
- }
-
+ var node *clusterNode
var ask bool
for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ {
if attempt > 0 {
time.Sleep(c.retryBackoff(attempt))
}
+ if node == nil {
+ var err error
+ _, node, err = c.cmdSlotAndNode(cmd)
+ if err != nil {
+ cmd.setErr(err)
+ break
+ }
+ }
+
+ var err error
if ask {
pipe := node.Client.Pipeline()
_ = pipe.Process(NewCmd("ASKING"))
@@ -687,15 +807,13 @@ func (c *ClusterClient) defaultProcess(cmd Cmder) error {
// If slave is loading - read from master.
if c.opt.ReadOnly && internal.IsLoadingError(err) {
- // TODO: race
- node.loading = time.Now()
+ node.MarkAsLoading()
continue
}
if internal.IsRetryableError(err, true) {
- var nodeErr error
- node, nodeErr = c.nodes.Random()
- if nodeErr != nil {
+ node, err = c.nodes.Random()
+ if err != nil {
break
}
continue
@@ -705,22 +823,18 @@ func (c *ClusterClient) defaultProcess(cmd Cmder) error {
var addr string
moved, ask, addr = internal.IsMovedError(err)
if moved || ask {
- c.lazyReloadState()
+ c.state.LazyReload()
- var nodeErr error
- node, nodeErr = c.nodes.GetOrCreate(addr)
- if nodeErr != nil {
+ node, err = c.nodes.GetOrCreate(addr)
+ if err != nil {
break
}
continue
}
if err == pool.ErrClosed {
- _, node, err = c.cmdSlotAndNode(state, cmd)
- if err != nil {
- cmd.setErr(err)
- return err
- }
+ node = nil
+ continue
}
break
@@ -732,7 +846,7 @@ func (c *ClusterClient) defaultProcess(cmd Cmder) error {
// ForEachMaster concurrently calls the fn on each master node in the cluster.
// It returns the first error if any.
func (c *ClusterClient) ForEachMaster(fn func(client *Client) error) error {
- state, err := c.state()
+ state, err := c.state.Get()
if err != nil {
return err
}
@@ -765,7 +879,7 @@ func (c *ClusterClient) ForEachMaster(fn func(client *Client) error) error {
// ForEachSlave concurrently calls the fn on each slave node in the cluster.
// It returns the first error if any.
func (c *ClusterClient) ForEachSlave(fn func(client *Client) error) error {
- state, err := c.state()
+ state, err := c.state.Get()
if err != nil {
return err
}
@@ -798,7 +912,7 @@ func (c *ClusterClient) ForEachSlave(fn func(client *Client) error) error {
// ForEachNode concurrently calls the fn on each known node in the cluster.
// It returns the first error if any.
func (c *ClusterClient) ForEachNode(fn func(client *Client) error) error {
- state, err := c.state()
+ state, err := c.state.Get()
if err != nil {
return err
}
@@ -838,7 +952,7 @@ func (c *ClusterClient) ForEachNode(fn func(client *Client) error) error {
func (c *ClusterClient) PoolStats() *PoolStats {
var acc PoolStats
- state, _ := c.state()
+ state, _ := c.state.Get()
if state == nil {
return &acc
}
@@ -868,46 +982,34 @@ func (c *ClusterClient) PoolStats() *PoolStats {
return &acc
}
-func (c *ClusterClient) lazyReloadState() {
- if !atomic.CompareAndSwapUint32(&c.reloading, 0, 1) {
- return
+func (c *ClusterClient) loadState() (*clusterState, error) {
+ addrs, err := c.nodes.Addrs()
+ if err != nil {
+ return nil, err
}
- go func() {
- defer atomic.StoreUint32(&c.reloading, 0)
-
- for {
- state, err := c.reloadState()
- if err == pool.ErrClosed {
- return
+ var firstErr error
+ for _, addr := range addrs {
+ node, err := c.nodes.GetOrCreate(addr)
+ if err != nil {
+ if firstErr == nil {
+ firstErr = err
}
+ continue
+ }
- if err != nil {
- time.Sleep(time.Millisecond)
- continue
+ slots, err := node.Client.ClusterSlots().Result()
+ if err != nil {
+ if firstErr == nil {
+ firstErr = err
}
-
- c._state.Store(state)
- time.Sleep(5 * time.Second)
- c.nodes.GC(state.generation)
- break
+ continue
}
- }()
-}
-// Not thread-safe.
-func (c *ClusterClient) reloadState() (*clusterState, error) {
- node, err := c.nodes.Random()
- if err != nil {
- return nil, err
- }
-
- slots, err := node.Client.ClusterSlots().Result()
- if err != nil {
- return nil, err
+ return newClusterState(c.nodes, slots, node.Client.opt.Addr)
}
- return newClusterState(c.nodes, slots, node.Client.opt.Addr)
+ return nil, firstErr
}
// reaper closes idle connections to the cluster.
@@ -991,7 +1093,7 @@ func (c *ClusterClient) defaultProcessPipeline(cmds []Cmder) error {
}
func (c *ClusterClient) mapCmdsByNode(cmds []Cmder) (map[*clusterNode][]Cmder, error) {
- state, err := c.state()
+ state, err := c.state.Get()
if err != nil {
setCmdsErr(cmds, err)
return nil, err
@@ -1024,15 +1126,17 @@ func (c *ClusterClient) remapCmds(cmds []Cmder, failedCmds map[*clusterNode][]Cm
func (c *ClusterClient) pipelineProcessCmds(
node *clusterNode, cn *pool.Conn, cmds []Cmder, failedCmds map[*clusterNode][]Cmder,
) error {
- cn.SetWriteTimeout(c.opt.WriteTimeout)
- if err := writeCmd(cn, cmds...); err != nil {
+ _ = cn.SetWriteTimeout(c.opt.WriteTimeout)
+
+ err := writeCmd(cn, cmds...)
+ if err != nil {
setCmdsErr(cmds, err)
failedCmds[node] = cmds
return err
}
// Set read timeout for all commands.
- cn.SetReadTimeout(c.opt.ReadTimeout)
+ _ = cn.SetReadTimeout(c.opt.ReadTimeout)
return c.pipelineReadCmds(cn, cmds, failedCmds)
}
@@ -1065,7 +1169,7 @@ func (c *ClusterClient) checkMovedErr(
moved, ask, addr := internal.IsMovedError(err)
if moved {
- c.lazyReloadState()
+ c.state.LazyReload()
node, err := c.nodes.GetOrCreate(addr)
if err != nil {
@@ -1103,7 +1207,7 @@ func (c *ClusterClient) TxPipelined(fn func(Pipeliner) error) ([]Cmder, error) {
}
func (c *ClusterClient) defaultProcessTxPipeline(cmds []Cmder) error {
- state, err := c.state()
+ state, err := c.state.Get()
if err != nil {
return err
}
@@ -1249,12 +1353,7 @@ func (c *ClusterClient) pubSub(channels []string) *PubSub {
slot = -1
}
- state, err := c.state()
- if err != nil {
- return nil, err
- }
-
- masterNode, err := state.slotMasterNode(slot)
+ masterNode, err := c.slotMasterNode(slot)
if err != nil {
return nil, err
}
@@ -1310,3 +1409,31 @@ func appendNode(nodes []*clusterNode, node *clusterNode) []*clusterNode {
}
return append(nodes, node)
}
+
+func appendIfNotExists(ss []string, es ...string) []string {
+loop:
+ for _, e := range es {
+ for _, s := range ss {
+ if s == e {
+ continue loop
+ }
+ }
+ ss = append(ss, e)
+ }
+ return ss
+}
+
+func remove(ss []string, es ...string) []string {
+ if len(es) == 0 {
+ return ss[:0]
+ }
+ for _, e := range es {
+ for i, s := range ss {
+ if s == e {
+ ss = append(ss[:i], ss[i+1:]...)
+ break
+ }
+ }
+ }
+ return ss
+}
diff --git a/vendor/github.com/go-redis/redis/cluster_test.go b/vendor/github.com/go-redis/redis/cluster_test.go
deleted file mode 100644
index 43f3261bc..000000000
--- a/vendor/github.com/go-redis/redis/cluster_test.go
+++ /dev/null
@@ -1,813 +0,0 @@
-package redis_test
-
-import (
- "bytes"
- "fmt"
- "net"
- "strconv"
- "strings"
- "sync"
- "testing"
- "time"
-
- "github.com/go-redis/redis"
- "github.com/go-redis/redis/internal/hashtag"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-type clusterScenario struct {
- ports []string
- nodeIds []string
- processes map[string]*redisProcess
- clients map[string]*redis.Client
-}
-
-func (s *clusterScenario) masters() []*redis.Client {
- result := make([]*redis.Client, 3)
- for pos, port := range s.ports[:3] {
- result[pos] = s.clients[port]
- }
- return result
-}
-
-func (s *clusterScenario) slaves() []*redis.Client {
- result := make([]*redis.Client, 3)
- for pos, port := range s.ports[3:] {
- result[pos] = s.clients[port]
- }
- return result
-}
-
-func (s *clusterScenario) addrs() []string {
- addrs := make([]string, len(s.ports))
- for i, port := range s.ports {
- addrs[i] = net.JoinHostPort("127.0.0.1", port)
- }
- return addrs
-}
-
-func (s *clusterScenario) clusterClient(opt *redis.ClusterOptions) *redis.ClusterClient {
- opt.Addrs = s.addrs()
- return redis.NewClusterClient(opt)
-}
-
-func startCluster(scenario *clusterScenario) error {
- // Start processes and collect node ids
- for pos, port := range scenario.ports {
- process, err := startRedis(port, "--cluster-enabled", "yes")
- if err != nil {
- return err
- }
-
- client := redis.NewClient(&redis.Options{
- Addr: ":" + port,
- })
-
- info, err := client.ClusterNodes().Result()
- if err != nil {
- return err
- }
-
- scenario.processes[port] = process
- scenario.clients[port] = client
- scenario.nodeIds[pos] = info[:40]
- }
-
- // Meet cluster nodes.
- for _, client := range scenario.clients {
- err := client.ClusterMeet("127.0.0.1", scenario.ports[0]).Err()
- if err != nil {
- return err
- }
- }
-
- // Bootstrap masters.
- slots := []int{0, 5000, 10000, 16384}
- for pos, master := range scenario.masters() {
- err := master.ClusterAddSlotsRange(slots[pos], slots[pos+1]-1).Err()
- if err != nil {
- return err
- }
- }
-
- // Bootstrap slaves.
- for idx, slave := range scenario.slaves() {
- masterId := scenario.nodeIds[idx]
-
- // Wait until master is available
- err := eventually(func() error {
- s := slave.ClusterNodes().Val()
- wanted := masterId
- if !strings.Contains(s, wanted) {
- return fmt.Errorf("%q does not contain %q", s, wanted)
- }
- return nil
- }, 10*time.Second)
- if err != nil {
- return err
- }
-
- err = slave.ClusterReplicate(masterId).Err()
- if err != nil {
- return err
- }
- }
-
- // Wait until all nodes have consistent info.
- for _, client := range scenario.clients {
- err := eventually(func() error {
- res, err := client.ClusterSlots().Result()
- if err != nil {
- return err
- }
- wanted := []redis.ClusterSlot{
- {0, 4999, []redis.ClusterNode{{"", "127.0.0.1:8220"}, {"", "127.0.0.1:8223"}}},
- {5000, 9999, []redis.ClusterNode{{"", "127.0.0.1:8221"}, {"", "127.0.0.1:8224"}}},
- {10000, 16383, []redis.ClusterNode{{"", "127.0.0.1:8222"}, {"", "127.0.0.1:8225"}}},
- }
- return assertSlotsEqual(res, wanted)
- }, 30*time.Second)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func assertSlotsEqual(slots, wanted []redis.ClusterSlot) error {
-outer_loop:
- for _, s2 := range wanted {
- for _, s1 := range slots {
- if slotEqual(s1, s2) {
- continue outer_loop
- }
- }
- return fmt.Errorf("%v not found in %v", s2, slots)
- }
- return nil
-}
-
-func slotEqual(s1, s2 redis.ClusterSlot) bool {
- if s1.Start != s2.Start {
- return false
- }
- if s1.End != s2.End {
- return false
- }
- if len(s1.Nodes) != len(s2.Nodes) {
- return false
- }
- for i, n1 := range s1.Nodes {
- if n1.Addr != s2.Nodes[i].Addr {
- return false
- }
- }
- return true
-}
-
-func stopCluster(scenario *clusterScenario) error {
- for _, client := range scenario.clients {
- if err := client.Close(); err != nil {
- return err
- }
- }
- for _, process := range scenario.processes {
- if err := process.Close(); err != nil {
- return err
- }
- }
- return nil
-}
-
-//------------------------------------------------------------------------------
-
-var _ = Describe("ClusterClient", func() {
- var opt *redis.ClusterOptions
- var client *redis.ClusterClient
-
- assertClusterClient := func() {
- It("should GET/SET/DEL", func() {
- val, err := client.Get("A").Result()
- Expect(err).To(Equal(redis.Nil))
- Expect(val).To(Equal(""))
-
- val, err = client.Set("A", "VALUE", 0).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("OK"))
-
- Eventually(func() string {
- return client.Get("A").Val()
- }, 30*time.Second).Should(Equal("VALUE"))
-
- cnt, err := client.Del("A").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(cnt).To(Equal(int64(1)))
- })
-
- It("follows redirects", func() {
- Expect(client.Set("A", "VALUE", 0).Err()).NotTo(HaveOccurred())
-
- slot := hashtag.Slot("A")
- client.SwapSlotNodes(slot)
-
- Eventually(func() string {
- return client.Get("A").Val()
- }, 30*time.Second).Should(Equal("VALUE"))
- })
-
- It("distributes keys", func() {
- for i := 0; i < 100; i++ {
- err := client.Set(fmt.Sprintf("key%d", i), "value", 0).Err()
- Expect(err).NotTo(HaveOccurred())
- }
-
- for _, master := range cluster.masters() {
- Eventually(func() string {
- return master.Info("keyspace").Val()
- }, 30*time.Second).Should(Or(
- ContainSubstring("keys=31"),
- ContainSubstring("keys=29"),
- ContainSubstring("keys=40"),
- ))
- }
- })
-
- It("distributes keys when using EVAL", func() {
- script := redis.NewScript(`
- local r = redis.call('SET', KEYS[1], ARGV[1])
- return r
- `)
-
- var key string
- for i := 0; i < 100; i++ {
- key = fmt.Sprintf("key%d", i)
- err := script.Run(client, []string{key}, "value").Err()
- Expect(err).NotTo(HaveOccurred())
- }
-
- for _, master := range cluster.masters() {
- Eventually(func() string {
- return master.Info("keyspace").Val()
- }, 30*time.Second).Should(Or(
- ContainSubstring("keys=31"),
- ContainSubstring("keys=29"),
- ContainSubstring("keys=40"),
- ))
- }
- })
-
- It("supports Watch", func() {
- var incr func(string) error
-
- // Transactionally increments key using GET and SET commands.
- incr = func(key string) error {
- err := client.Watch(func(tx *redis.Tx) error {
- n, err := tx.Get(key).Int64()
- if err != nil && err != redis.Nil {
- return err
- }
-
- _, err = tx.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Set(key, strconv.FormatInt(n+1, 10), 0)
- return nil
- })
- return err
- }, key)
- if err == redis.TxFailedErr {
- return incr(key)
- }
- return err
- }
-
- var wg sync.WaitGroup
- for i := 0; i < 100; i++ {
- wg.Add(1)
- go func() {
- defer GinkgoRecover()
- defer wg.Done()
-
- err := incr("key")
- Expect(err).NotTo(HaveOccurred())
- }()
- }
- wg.Wait()
-
- n, err := client.Get("key").Int64()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(100)))
- })
-
- Describe("pipelining", func() {
- var pipe *redis.Pipeline
-
- assertPipeline := func() {
- keys := []string{"A", "B", "C", "D", "E", "F", "G"}
-
- It("follows redirects", func() {
- for _, key := range keys {
- slot := hashtag.Slot(key)
- client.SwapSlotNodes(slot)
- }
-
- for i, key := range keys {
- pipe.Set(key, key+"_value", 0)
- pipe.Expire(key, time.Duration(i+1)*time.Hour)
- }
- cmds, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(14))
-
- for _, key := range keys {
- slot := hashtag.Slot(key)
- client.SwapSlotNodes(slot)
- }
-
- for _, key := range keys {
- pipe.Get(key)
- pipe.TTL(key)
- }
- cmds, err = pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(14))
-
- for i, key := range keys {
- get := cmds[i*2].(*redis.StringCmd)
- Expect(get.Val()).To(Equal(key + "_value"))
-
- ttl := cmds[(i*2)+1].(*redis.DurationCmd)
- dur := time.Duration(i+1) * time.Hour
- Expect(ttl.Val()).To(BeNumerically("~", dur, 5*time.Second))
- }
- })
-
- It("works with missing keys", func() {
- pipe.Set("A", "A_value", 0)
- pipe.Set("C", "C_value", 0)
- _, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
-
- a := pipe.Get("A")
- b := pipe.Get("B")
- c := pipe.Get("C")
- cmds, err := pipe.Exec()
- Expect(err).To(Equal(redis.Nil))
- Expect(cmds).To(HaveLen(3))
-
- Expect(a.Err()).NotTo(HaveOccurred())
- Expect(a.Val()).To(Equal("A_value"))
-
- Expect(b.Err()).To(Equal(redis.Nil))
- Expect(b.Val()).To(Equal(""))
-
- Expect(c.Err()).NotTo(HaveOccurred())
- Expect(c.Val()).To(Equal("C_value"))
- })
- }
-
- Describe("with Pipeline", func() {
- BeforeEach(func() {
- pipe = client.Pipeline().(*redis.Pipeline)
- })
-
- AfterEach(func() {
- Expect(pipe.Close()).NotTo(HaveOccurred())
- })
-
- assertPipeline()
- })
-
- Describe("with TxPipeline", func() {
- BeforeEach(func() {
- pipe = client.TxPipeline().(*redis.Pipeline)
- })
-
- AfterEach(func() {
- Expect(pipe.Close()).NotTo(HaveOccurred())
- })
-
- assertPipeline()
- })
- })
-
- It("supports PubSub", func() {
- pubsub := client.Subscribe("mychannel")
- defer pubsub.Close()
-
- Eventually(func() error {
- _, err := client.Publish("mychannel", "hello").Result()
- if err != nil {
- return err
- }
-
- msg, err := pubsub.ReceiveTimeout(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())
- })
- }
-
- Describe("ClusterClient", func() {
- BeforeEach(func() {
- opt = redisClusterOptions()
- client = cluster.clusterClient(opt)
-
- _ = client.ForEachMaster(func(master *redis.Client) error {
- return master.FlushDB().Err()
- })
- })
-
- AfterEach(func() {
- _ = client.ForEachMaster(func(master *redis.Client) error {
- return master.FlushDB().Err()
- })
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("returns pool stats", func() {
- Expect(client.PoolStats()).To(BeAssignableToTypeOf(&redis.PoolStats{}))
- })
-
- It("removes idle connections", func() {
- stats := client.PoolStats()
- Expect(stats.TotalConns).NotTo(BeZero())
- Expect(stats.FreeConns).NotTo(BeZero())
-
- time.Sleep(2 * time.Second)
-
- stats = client.PoolStats()
- Expect(stats.TotalConns).To(BeZero())
- Expect(stats.FreeConns).To(BeZero())
- })
-
- It("returns an error when there are no attempts left", func() {
- opt := redisClusterOptions()
- opt.MaxRedirects = -1
- client := cluster.clusterClient(opt)
-
- slot := hashtag.Slot("A")
- client.SwapSlotNodes(slot)
-
- err := client.Get("A").Err()
- Expect(err).To(HaveOccurred())
- Expect(err.Error()).To(ContainSubstring("MOVED"))
-
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("calls fn for every master node", func() {
- for i := 0; i < 10; i++ {
- Expect(client.Set(strconv.Itoa(i), "", 0).Err()).NotTo(HaveOccurred())
- }
-
- err := client.ForEachMaster(func(master *redis.Client) error {
- return master.FlushDB().Err()
- })
- Expect(err).NotTo(HaveOccurred())
-
- size, err := client.DBSize().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(size).To(Equal(int64(0)))
- })
-
- It("should CLUSTER SLOTS", func() {
- res, err := client.ClusterSlots().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(res).To(HaveLen(3))
-
- wanted := []redis.ClusterSlot{
- {0, 4999, []redis.ClusterNode{{"", "127.0.0.1:8220"}, {"", "127.0.0.1:8223"}}},
- {5000, 9999, []redis.ClusterNode{{"", "127.0.0.1:8221"}, {"", "127.0.0.1:8224"}}},
- {10000, 16383, []redis.ClusterNode{{"", "127.0.0.1:8222"}, {"", "127.0.0.1:8225"}}},
- }
- Expect(assertSlotsEqual(res, wanted)).NotTo(HaveOccurred())
- })
-
- It("should CLUSTER NODES", func() {
- res, err := client.ClusterNodes().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(len(res)).To(BeNumerically(">", 400))
- })
-
- It("should CLUSTER INFO", func() {
- res, err := client.ClusterInfo().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(res).To(ContainSubstring("cluster_known_nodes:6"))
- })
-
- It("should CLUSTER KEYSLOT", func() {
- hashSlot, err := client.ClusterKeySlot("somekey").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(hashSlot).To(Equal(int64(hashtag.Slot("somekey"))))
- })
-
- It("should CLUSTER COUNT-FAILURE-REPORTS", func() {
- n, err := client.ClusterCountFailureReports(cluster.nodeIds[0]).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(0)))
- })
-
- It("should CLUSTER COUNTKEYSINSLOT", func() {
- n, err := client.ClusterCountKeysInSlot(10).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(0)))
- })
-
- It("should CLUSTER SAVECONFIG", func() {
- res, err := client.ClusterSaveConfig().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(res).To(Equal("OK"))
- })
-
- It("should CLUSTER SLAVES", func() {
- nodesList, err := client.ClusterSlaves(cluster.nodeIds[0]).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(nodesList).Should(ContainElement(ContainSubstring("slave")))
- 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()
- })
-
- Describe("ClusterClient failover", func() {
- BeforeEach(func() {
- opt = redisClusterOptions()
- client = cluster.clusterClient(opt)
-
- _ = client.ForEachMaster(func(master *redis.Client) error {
- return master.FlushDB().Err()
- })
-
- _ = client.ForEachSlave(func(slave *redis.Client) error {
- Eventually(func() int64 {
- return client.DBSize().Val()
- }, 30*time.Second).Should(Equal(int64(0)))
- return slave.ClusterFailover().Err()
- })
- })
-
- AfterEach(func() {
- _ = client.ForEachMaster(func(master *redis.Client) error {
- return master.FlushDB().Err()
- })
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- assertClusterClient()
- })
-
- Describe("ClusterClient with RouteByLatency", func() {
- BeforeEach(func() {
- opt = redisClusterOptions()
- opt.RouteByLatency = true
- client = cluster.clusterClient(opt)
-
- _ = client.ForEachMaster(func(master *redis.Client) error {
- return master.FlushDB().Err()
- })
-
- _ = client.ForEachSlave(func(slave *redis.Client) error {
- Eventually(func() int64 {
- return client.DBSize().Val()
- }, 30*time.Second).Should(Equal(int64(0)))
- return nil
- })
- })
-
- AfterEach(func() {
- _ = client.ForEachMaster(func(master *redis.Client) error {
- return master.FlushDB().Err()
- })
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- assertClusterClient()
- })
-})
-
-var _ = Describe("ClusterClient without nodes", func() {
- var client *redis.ClusterClient
-
- BeforeEach(func() {
- client = redis.NewClusterClient(&redis.ClusterOptions{})
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("Ping returns an error", func() {
- err := client.Ping().Err()
- Expect(err).To(MatchError("redis: cluster has no nodes"))
- })
-
- It("pipeline returns an error", func() {
- _, err := client.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Ping()
- return nil
- })
- Expect(err).To(MatchError("redis: cluster has no nodes"))
- })
-})
-
-var _ = Describe("ClusterClient without valid nodes", func() {
- var client *redis.ClusterClient
-
- BeforeEach(func() {
- client = redis.NewClusterClient(&redis.ClusterOptions{
- Addrs: []string{redisAddr},
- })
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("returns an error", func() {
- err := client.Ping().Err()
- Expect(err).To(MatchError("redis: cannot load cluster slots"))
- })
-
- It("pipeline returns an error", func() {
- _, err := client.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Ping()
- return nil
- })
- Expect(err).To(MatchError("redis: cannot load cluster slots"))
- })
-})
-
-var _ = Describe("ClusterClient timeout", func() {
- var client *redis.ClusterClient
-
- AfterEach(func() {
- _ = client.Close()
- })
-
- testTimeout := func() {
- It("Ping timeouts", func() {
- err := client.Ping().Err()
- Expect(err).To(HaveOccurred())
- Expect(err.(net.Error).Timeout()).To(BeTrue())
- })
-
- It("Pipeline timeouts", func() {
- _, err := client.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Ping()
- return nil
- })
- Expect(err).To(HaveOccurred())
- Expect(err.(net.Error).Timeout()).To(BeTrue())
- })
-
- It("Tx timeouts", func() {
- err := client.Watch(func(tx *redis.Tx) error {
- return tx.Ping().Err()
- }, "foo")
- Expect(err).To(HaveOccurred())
- Expect(err.(net.Error).Timeout()).To(BeTrue())
- })
-
- It("Tx Pipeline timeouts", func() {
- err := client.Watch(func(tx *redis.Tx) error {
- _, err := tx.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Ping()
- return nil
- })
- return err
- }, "foo")
- Expect(err).To(HaveOccurred())
- Expect(err.(net.Error).Timeout()).To(BeTrue())
- })
- }
-
- const pause = time.Second
-
- Context("read/write timeout", func() {
- BeforeEach(func() {
- opt := redisClusterOptions()
- opt.ReadTimeout = 100 * time.Millisecond
- opt.WriteTimeout = 100 * time.Millisecond
- opt.MaxRedirects = 1
- client = cluster.clusterClient(opt)
-
- err := client.ForEachNode(func(client *redis.Client) error {
- return client.ClientPause(pause).Err()
- })
- Expect(err).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- client.ForEachNode(func(client *redis.Client) error {
- Eventually(func() error {
- return client.Ping().Err()
- }, 2*pause).ShouldNot(HaveOccurred())
- return nil
- })
- })
-
- testTimeout()
- })
-})
-
-//------------------------------------------------------------------------------
-
-func BenchmarkRedisClusterPing(b *testing.B) {
- if testing.Short() {
- b.Skip("skipping in short mode")
- }
-
- cluster := &clusterScenario{
- ports: []string{"8220", "8221", "8222", "8223", "8224", "8225"},
- nodeIds: make([]string, 6),
- processes: make(map[string]*redisProcess, 6),
- clients: make(map[string]*redis.Client, 6),
- }
-
- if err := startCluster(cluster); err != nil {
- b.Fatal(err)
- }
- defer stopCluster(cluster)
-
- client := cluster.clusterClient(redisClusterOptions())
- defer client.Close()
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- if err := client.Ping().Err(); err != nil {
- b.Fatal(err)
- }
- }
- })
-}
-
-func BenchmarkRedisClusterSetString(b *testing.B) {
- if testing.Short() {
- b.Skip("skipping in short mode")
- }
-
- cluster := &clusterScenario{
- ports: []string{"8220", "8221", "8222", "8223", "8224", "8225"},
- nodeIds: make([]string, 6),
- processes: make(map[string]*redisProcess, 6),
- clients: make(map[string]*redis.Client, 6),
- }
-
- if err := startCluster(cluster); err != nil {
- b.Fatal(err)
- }
- defer stopCluster(cluster)
-
- client := cluster.clusterClient(redisClusterOptions())
- defer client.Close()
-
- value := string(bytes.Repeat([]byte{'1'}, 10000))
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- if err := client.Set("key", value, 0).Err(); err != nil {
- b.Fatal(err)
- }
- }
- })
-}
diff --git a/vendor/github.com/go-redis/redis/command.go b/vendor/github.com/go-redis/redis/command.go
index 480a5ce19..1588ca251 100644
--- a/vendor/github.com/go-redis/redis/command.go
+++ b/vendor/github.com/go-redis/redis/command.go
@@ -10,6 +10,7 @@ import (
"github.com/go-redis/redis/internal"
"github.com/go-redis/redis/internal/pool"
"github.com/go-redis/redis/internal/proto"
+ "github.com/go-redis/redis/internal/util"
)
type Cmder interface {
@@ -436,7 +437,7 @@ func NewStringCmd(args ...interface{}) *StringCmd {
}
func (cmd *StringCmd) Val() string {
- return internal.BytesToString(cmd.val)
+ return util.BytesToString(cmd.val)
}
func (cmd *StringCmd) Result() (string, error) {
@@ -1022,3 +1023,26 @@ func (cmd *CommandsInfoCmd) readReply(cn *pool.Conn) error {
cmd.val = v.(map[string]*CommandInfo)
return nil
}
+
+//------------------------------------------------------------------------------
+
+type cmdsInfoCache struct {
+ once internal.Once
+ cmds map[string]*CommandInfo
+}
+
+func newCmdsInfoCache() *cmdsInfoCache {
+ return &cmdsInfoCache{}
+}
+
+func (c *cmdsInfoCache) Do(fn func() (map[string]*CommandInfo, error)) (map[string]*CommandInfo, error) {
+ err := c.once.Do(func() error {
+ cmds, err := fn()
+ if err != nil {
+ return err
+ }
+ c.cmds = cmds
+ return nil
+ })
+ return c.cmds, err
+}
diff --git a/vendor/github.com/go-redis/redis/command_test.go b/vendor/github.com/go-redis/redis/command_test.go
deleted file mode 100644
index e42375eda..000000000
--- a/vendor/github.com/go-redis/redis/command_test.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package redis_test
-
-import (
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("Cmd", func() {
- var client *redis.Client
-
- BeforeEach(func() {
- client = redis.NewClient(redisOptions())
- Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("implements Stringer", func() {
- set := client.Set("foo", "bar", 0)
- Expect(set.String()).To(Equal("set foo bar: OK"))
-
- get := client.Get("foo")
- Expect(get.String()).To(Equal("get foo: bar"))
- })
-
- It("has val/err", func() {
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- get := client.Get("key")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("hello"))
-
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
- })
-
- It("has helpers", func() {
- set := client.Set("key", "10", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
-
- n, err := client.Get("key").Int64()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(10)))
-
- un, err := client.Get("key").Uint64()
- Expect(err).NotTo(HaveOccurred())
- Expect(un).To(Equal(uint64(10)))
-
- f, err := client.Get("key").Float64()
- Expect(err).NotTo(HaveOccurred())
- Expect(f).To(Equal(float64(10)))
- })
-
-})
diff --git a/vendor/github.com/go-redis/redis/commands.go b/vendor/github.com/go-redis/redis/commands.go
index 569342cfa..a3dacacd2 100644
--- a/vendor/github.com/go-redis/redis/commands.go
+++ b/vendor/github.com/go-redis/redis/commands.go
@@ -1,6 +1,7 @@
package redis
import (
+ "errors"
"io"
"time"
@@ -38,6 +39,22 @@ func formatSec(dur time.Duration) int64 {
return int64(dur / time.Second)
}
+func appendArgs(dst, src []interface{}) []interface{} {
+ if len(src) == 1 {
+ if ss, ok := src[0].([]string); ok {
+ for _, s := range ss {
+ dst = append(dst, s)
+ }
+ return dst
+ }
+ }
+
+ for _, v := range src {
+ dst = append(dst, v)
+ }
+ return dst
+}
+
type Cmdable interface {
Pipeline() Pipeliner
Pipelined(fn func(Pipeliner) error) ([]Cmder, error)
@@ -70,8 +87,10 @@ type Cmdable interface {
RenameNX(key, newkey string) *BoolCmd
Restore(key string, ttl time.Duration, value string) *StatusCmd
RestoreReplace(key string, ttl time.Duration, value string) *StatusCmd
- Sort(key string, sort Sort) *StringSliceCmd
- SortInterfaces(key string, sort Sort) *SliceCmd
+ Sort(key string, sort *Sort) *StringSliceCmd
+ SortStore(key, store string, sort *Sort) *IntCmd
+ SortInterfaces(key string, sort *Sort) *SliceCmd
+ Touch(keys ...string) *IntCmd
TTL(key string) *DurationCmd
Type(key string) *StatusCmd
Scan(cursor uint64, match string, count int64) *ScanCmd
@@ -195,6 +214,7 @@ type Cmdable interface {
ConfigGet(parameter string) *SliceCmd
ConfigResetStat() *StatusCmd
ConfigSet(parameter, value string) *StatusCmd
+ ConfigRewrite() *StatusCmd
DBSize() *IntCmd
FlushAll() *StatusCmd
FlushAllAsync() *StatusCmd
@@ -210,7 +230,7 @@ type Cmdable interface {
Time() *TimeCmd
Eval(script string, keys []string, args ...interface{}) *Cmd
EvalSha(sha1 string, keys []string, args ...interface{}) *Cmd
- ScriptExists(scripts ...string) *BoolSliceCmd
+ ScriptExists(hashes ...string) *BoolSliceCmd
ScriptFlush() *StatusCmd
ScriptKill() *StatusCmd
ScriptLoad(script string) *StringCmd
@@ -252,6 +272,7 @@ type StatefulCmdable interface {
Cmdable
Auth(password string) *StatusCmd
Select(index int) *StatusCmd
+ SwapDB(index1, index2 int) *StatusCmd
ClientSetName(name string) *BoolCmd
ReadOnly() *StatusCmd
ReadWrite() *StatusCmd
@@ -316,6 +337,12 @@ func (c *statefulCmdable) Select(index int) *StatusCmd {
return cmd
}
+func (c *statefulCmdable) SwapDB(index1, index2 int) *StatusCmd {
+ cmd := NewStatusCmd("swapdb", index1, index2)
+ c.process(cmd)
+ return cmd
+}
+
//------------------------------------------------------------------------------
func (c *cmdable) Del(keys ...string) *IntCmd {
@@ -484,11 +511,10 @@ func (c *cmdable) RestoreReplace(key string, ttl time.Duration, value string) *S
type Sort struct {
By string
- Offset, Count float64
+ Offset, Count int64
Get []string
Order string
- IsAlpha bool
- Store string
+ Alpha bool
}
func (sort *Sort) args(key string) []interface{} {
@@ -505,27 +531,45 @@ func (sort *Sort) args(key string) []interface{} {
if sort.Order != "" {
args = append(args, sort.Order)
}
- if sort.IsAlpha {
+ if sort.Alpha {
args = append(args, "alpha")
}
- if sort.Store != "" {
- args = append(args, "store", sort.Store)
- }
return args
}
-func (c *cmdable) Sort(key string, sort Sort) *StringSliceCmd {
+func (c *cmdable) Sort(key string, sort *Sort) *StringSliceCmd {
cmd := NewStringSliceCmd(sort.args(key)...)
c.process(cmd)
return cmd
}
-func (c *cmdable) SortInterfaces(key string, sort Sort) *SliceCmd {
+func (c *cmdable) SortStore(key, store string, sort *Sort) *IntCmd {
+ args := sort.args(key)
+ if store != "" {
+ args = append(args, "store", store)
+ }
+ cmd := NewIntCmd(args...)
+ c.process(cmd)
+ return cmd
+}
+
+func (c *cmdable) SortInterfaces(key string, sort *Sort) *SliceCmd {
cmd := NewSliceCmd(sort.args(key)...)
c.process(cmd)
return cmd
}
+func (c *cmdable) Touch(keys ...string) *IntCmd {
+ args := make([]interface{}, len(keys)+1)
+ args[0] = "touch"
+ for i, key := range keys {
+ args[i+1] = key
+ }
+ cmd := NewIntCmd(args...)
+ c.process(cmd)
+ return cmd
+}
+
func (c *cmdable) TTL(key string) *DurationCmd {
cmd := NewDurationCmd(time.Second, "ttl", key)
c.process(cmd)
@@ -732,22 +776,18 @@ func (c *cmdable) MGet(keys ...string) *SliceCmd {
}
func (c *cmdable) MSet(pairs ...interface{}) *StatusCmd {
- args := make([]interface{}, 1+len(pairs))
+ args := make([]interface{}, 1, 1+len(pairs))
args[0] = "mset"
- for i, pair := range pairs {
- args[1+i] = pair
- }
+ args = appendArgs(args, pairs)
cmd := NewStatusCmd(args...)
c.process(cmd)
return cmd
}
func (c *cmdable) MSetNX(pairs ...interface{}) *BoolCmd {
- args := make([]interface{}, 1+len(pairs))
+ args := make([]interface{}, 1, 1+len(pairs))
args[0] = "msetnx"
- for i, pair := range pairs {
- args[1+i] = pair
- }
+ args = appendArgs(args, pairs)
cmd := NewBoolCmd(args...)
c.process(cmd)
return cmd
@@ -1012,12 +1052,10 @@ func (c *cmdable) LPop(key string) *StringCmd {
}
func (c *cmdable) LPush(key string, values ...interface{}) *IntCmd {
- args := make([]interface{}, 2+len(values))
+ args := make([]interface{}, 2, 2+len(values))
args[0] = "lpush"
args[1] = key
- for i, value := range values {
- args[2+i] = value
- }
+ args = appendArgs(args, values)
cmd := NewIntCmd(args...)
c.process(cmd)
return cmd
@@ -1076,12 +1114,10 @@ func (c *cmdable) RPopLPush(source, destination string) *StringCmd {
}
func (c *cmdable) RPush(key string, values ...interface{}) *IntCmd {
- args := make([]interface{}, 2+len(values))
+ args := make([]interface{}, 2, 2+len(values))
args[0] = "rpush"
args[1] = key
- for i, value := range values {
- args[2+i] = value
- }
+ args = appendArgs(args, values)
cmd := NewIntCmd(args...)
c.process(cmd)
return cmd
@@ -1096,12 +1132,10 @@ func (c *cmdable) RPushX(key string, value interface{}) *IntCmd {
//------------------------------------------------------------------------------
func (c *cmdable) SAdd(key string, members ...interface{}) *IntCmd {
- args := make([]interface{}, 2+len(members))
+ args := make([]interface{}, 2, 2+len(members))
args[0] = "sadd"
args[1] = key
- for i, member := range members {
- args[2+i] = member
- }
+ args = appendArgs(args, members)
cmd := NewIntCmd(args...)
c.process(cmd)
return cmd
@@ -1214,12 +1248,10 @@ func (c *cmdable) SRandMemberN(key string, count int64) *StringSliceCmd {
}
func (c *cmdable) SRem(key string, members ...interface{}) *IntCmd {
- args := make([]interface{}, 2+len(members))
+ args := make([]interface{}, 2, 2+len(members))
args[0] = "srem"
args[1] = key
- for i, member := range members {
- args[2+i] = member
- }
+ args = appendArgs(args, members)
cmd := NewIntCmd(args...)
c.process(cmd)
return cmd
@@ -1479,12 +1511,10 @@ func (c *cmdable) ZRank(key, member string) *IntCmd {
}
func (c *cmdable) ZRem(key string, members ...interface{}) *IntCmd {
- args := make([]interface{}, 2+len(members))
+ args := make([]interface{}, 2, 2+len(members))
args[0] = "zrem"
args[1] = key
- for i, member := range members {
- args[2+i] = member
- }
+ args = appendArgs(args, members)
cmd := NewIntCmd(args...)
c.process(cmd)
return cmd
@@ -1600,12 +1630,10 @@ func (c *cmdable) ZUnionStore(dest string, store ZStore, keys ...string) *IntCmd
//------------------------------------------------------------------------------
func (c *cmdable) PFAdd(key string, els ...interface{}) *IntCmd {
- args := make([]interface{}, 2+len(els))
+ args := make([]interface{}, 2, 2+len(els))
args[0] = "pfadd"
args[1] = key
- for i, el := range els {
- args[2+i] = el
- }
+ args = appendArgs(args, els)
cmd := NewIntCmd(args...)
c.process(cmd)
return cmd
@@ -1698,6 +1726,12 @@ func (c *cmdable) ConfigSet(parameter, value string) *StatusCmd {
return cmd
}
+func (c *cmdable) ConfigRewrite() *StatusCmd {
+ cmd := NewStatusCmd("config", "rewrite")
+ c.process(cmd)
+ return cmd
+}
+
// Deperecated. Use DBSize instead.
func (c *cmdable) DbSize() *IntCmd {
return c.DBSize()
@@ -1776,7 +1810,7 @@ func (c *cmdable) shutdown(modifier string) *StatusCmd {
}
} else {
// Server did not quit. String reply contains the reason.
- cmd.err = internal.RedisError(cmd.val)
+ cmd.err = errors.New(cmd.val)
cmd.val = ""
}
return cmd
@@ -1817,45 +1851,39 @@ func (c *cmdable) Time() *TimeCmd {
//------------------------------------------------------------------------------
func (c *cmdable) Eval(script string, keys []string, args ...interface{}) *Cmd {
- cmdArgs := make([]interface{}, 3+len(keys)+len(args))
+ 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
}
- pos := 3 + len(keys)
- for i, arg := range args {
- cmdArgs[pos+i] = arg
- }
+ cmdArgs = appendArgs(cmdArgs, args)
cmd := NewCmd(cmdArgs...)
c.process(cmd)
return cmd
}
func (c *cmdable) EvalSha(sha1 string, keys []string, args ...interface{}) *Cmd {
- cmdArgs := make([]interface{}, 3+len(keys)+len(args))
+ cmdArgs := make([]interface{}, 3+len(keys), 3+len(keys)+len(args))
cmdArgs[0] = "evalsha"
cmdArgs[1] = sha1
cmdArgs[2] = len(keys)
for i, key := range keys {
cmdArgs[3+i] = key
}
- pos := 3 + len(keys)
- for i, arg := range args {
- cmdArgs[pos+i] = arg
- }
+ cmdArgs = appendArgs(cmdArgs, args)
cmd := NewCmd(cmdArgs...)
c.process(cmd)
return cmd
}
-func (c *cmdable) ScriptExists(scripts ...string) *BoolSliceCmd {
- args := make([]interface{}, 2+len(scripts))
+func (c *cmdable) ScriptExists(hashes ...string) *BoolSliceCmd {
+ args := make([]interface{}, 2+len(hashes))
args[0] = "script"
args[1] = "exists"
- for i, script := range scripts {
- args[2+i] = script
+ for i, hash := range hashes {
+ args[2+i] = hash
}
cmd := NewBoolSliceCmd(args...)
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
deleted file mode 100644
index 715379556..000000000
--- a/vendor/github.com/go-redis/redis/commands_test.go
+++ /dev/null
@@ -1,2968 +0,0 @@
-package redis_test
-
-import (
- "encoding/json"
- "fmt"
- "reflect"
- "time"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-
- "github.com/go-redis/redis"
-)
-
-var _ = Describe("Commands", func() {
- var client *redis.Client
-
- BeforeEach(func() {
- client = redis.NewClient(redisOptions())
- Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- Describe("server", func() {
-
- It("should Auth", func() {
- cmds, err := client.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Auth("password")
- pipe.Auth("")
- return nil
- })
- Expect(err).To(MatchError("ERR Client sent AUTH, but no password is set"))
- Expect(cmds[0].Err()).To(MatchError("ERR Client sent AUTH, but no password is set"))
- Expect(cmds[1].Err()).To(MatchError("ERR Client sent AUTH, but no password is set"))
-
- stats := client.PoolStats()
- Expect(stats.Hits).To(Equal(uint32(1)))
- Expect(stats.Misses).To(Equal(uint32(1)))
- Expect(stats.Timeouts).To(Equal(uint32(0)))
- Expect(stats.TotalConns).To(Equal(uint32(1)))
- Expect(stats.FreeConns).To(Equal(uint32(1)))
- })
-
- It("should Echo", func() {
- pipe := client.Pipeline()
- echo := pipe.Echo("hello")
- _, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
-
- Expect(echo.Err()).NotTo(HaveOccurred())
- Expect(echo.Val()).To(Equal("hello"))
- })
-
- It("should Ping", func() {
- ping := client.Ping()
- Expect(ping.Err()).NotTo(HaveOccurred())
- Expect(ping.Val()).To(Equal("PONG"))
- })
-
- It("should Wait", func() {
- // assume testing on single redis instance
- start := time.Now()
- wait := client.Wait(1, time.Second)
- Expect(wait.Err()).NotTo(HaveOccurred())
- Expect(wait.Val()).To(Equal(int64(0)))
- Expect(time.Now()).To(BeTemporally("~", start.Add(time.Second), 800*time.Millisecond))
- })
-
- It("should Select", func() {
- pipe := client.Pipeline()
- sel := pipe.Select(1)
- _, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
-
- Expect(sel.Err()).NotTo(HaveOccurred())
- Expect(sel.Val()).To(Equal("OK"))
- })
-
- It("should BgRewriteAOF", func() {
- Skip("flaky test")
-
- val, err := client.BgRewriteAOF().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(ContainSubstring("Background append only file rewriting"))
- })
-
- It("should BgSave", func() {
- Skip("flaky test")
-
- // workaround for "ERR Can't BGSAVE while AOF log rewriting is in progress"
- Eventually(func() string {
- return client.BgSave().Val()
- }, "30s").Should(Equal("Background saving started"))
- })
-
- It("should ClientKill", func() {
- r := client.ClientKill("1.1.1.1:1111")
- Expect(r.Err()).To(MatchError("ERR No such client"))
- Expect(r.Val()).To(Equal(""))
- })
-
- It("should ClientPause", func() {
- err := client.ClientPause(time.Second).Err()
- Expect(err).NotTo(HaveOccurred())
-
- start := time.Now()
- err = client.Ping().Err()
- Expect(err).NotTo(HaveOccurred())
- Expect(time.Now()).To(BeTemporally("~", start.Add(time.Second), 800*time.Millisecond))
- })
-
- It("should ClientSetName and ClientGetName", func() {
- pipe := client.Pipeline()
- set := pipe.ClientSetName("theclientname")
- get := pipe.ClientGetName()
- _, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
-
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(BeTrue())
-
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("theclientname"))
- })
-
- It("should ConfigGet", func() {
- val, err := client.ConfigGet("*").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).NotTo(BeEmpty())
- })
-
- It("should ConfigResetStat", func() {
- r := client.ConfigResetStat()
- Expect(r.Err()).NotTo(HaveOccurred())
- Expect(r.Val()).To(Equal("OK"))
- })
-
- It("should ConfigSet", func() {
- configGet := client.ConfigGet("maxmemory")
- Expect(configGet.Err()).NotTo(HaveOccurred())
- Expect(configGet.Val()).To(HaveLen(2))
- Expect(configGet.Val()[0]).To(Equal("maxmemory"))
-
- configSet := client.ConfigSet("maxmemory", configGet.Val()[1].(string))
- Expect(configSet.Err()).NotTo(HaveOccurred())
- Expect(configSet.Val()).To(Equal("OK"))
- })
-
- It("should DBSize", func() {
- size, err := client.DBSize().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(size).To(Equal(int64(0)))
- })
-
- It("should Info", func() {
- info := client.Info()
- Expect(info.Err()).NotTo(HaveOccurred())
- Expect(info.Val()).NotTo(Equal(""))
- })
-
- It("should Info cpu", func() {
- info := client.Info("cpu")
- Expect(info.Err()).NotTo(HaveOccurred())
- Expect(info.Val()).NotTo(Equal(""))
- Expect(info.Val()).To(ContainSubstring(`used_cpu_sys`))
- })
-
- It("should LastSave", func() {
- lastSave := client.LastSave()
- Expect(lastSave.Err()).NotTo(HaveOccurred())
- Expect(lastSave.Val()).NotTo(Equal(0))
- })
-
- It("should Save", func() {
- // workaround for "ERR Background save already in progress"
- Eventually(func() string {
- return client.Save().Val()
- }, "10s").Should(Equal("OK"))
- })
-
- It("should SlaveOf", func() {
- slaveOf := client.SlaveOf("localhost", "8888")
- Expect(slaveOf.Err()).NotTo(HaveOccurred())
- Expect(slaveOf.Val()).To(Equal("OK"))
-
- slaveOf = client.SlaveOf("NO", "ONE")
- Expect(slaveOf.Err()).NotTo(HaveOccurred())
- Expect(slaveOf.Val()).To(Equal("OK"))
- })
-
- It("should Time", func() {
- tm, err := client.Time().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(tm).To(BeTemporally("~", time.Now(), 3*time.Second))
- })
-
- It("Should Command", func() {
- cmds, err := client.Command().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(len(cmds)).To(BeNumerically("~", 180, 10))
-
- cmd := cmds["mget"]
- Expect(cmd.Name).To(Equal("mget"))
- Expect(cmd.Arity).To(Equal(int8(-2)))
- Expect(cmd.Flags).To(ContainElement("readonly"))
- Expect(cmd.FirstKeyPos).To(Equal(int8(1)))
- Expect(cmd.LastKeyPos).To(Equal(int8(-1)))
- Expect(cmd.StepCount).To(Equal(int8(1)))
-
- 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)))
- Expect(cmd.StepCount).To(Equal(int8(0)))
- })
-
- })
-
- Describe("debugging", func() {
-
- It("should DebugObject", func() {
- debug := client.DebugObject("foo")
- Expect(debug.Err()).To(HaveOccurred())
- Expect(debug.Err().Error()).To(Equal("ERR no such key"))
-
- client.Set("foo", "bar", 0)
- debug = client.DebugObject("foo")
- Expect(debug.Err()).NotTo(HaveOccurred())
- Expect(debug.Val()).To(ContainSubstring(`serializedlength:4`))
- })
-
- })
-
- Describe("keys", func() {
-
- It("should Del", func() {
- err := client.Set("key1", "Hello", 0).Err()
- Expect(err).NotTo(HaveOccurred())
- err = client.Set("key2", "World", 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- n, err := client.Del("key1", "key2", "key3").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(2)))
- })
-
- It("should Unlink", func() {
- err := client.Set("key1", "Hello", 0).Err()
- Expect(err).NotTo(HaveOccurred())
- err = client.Set("key2", "World", 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- n, err := client.Unlink("key1", "key2", "key3").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(2)))
- })
-
- It("should Dump", func() {
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- dump := client.Dump("key")
- Expect(dump.Err()).NotTo(HaveOccurred())
- Expect(dump.Val()).NotTo(BeEmpty())
- })
-
- It("should Exists", func() {
- set := client.Set("key1", "Hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- n, err := client.Exists("key1").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(1)))
-
- n, err = client.Exists("key2").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(0)))
-
- n, err = client.Exists("key1", "key2").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(1)))
-
- n, err = client.Exists("key1", "key1").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(2)))
- })
-
- It("should Expire", func() {
- set := client.Set("key", "Hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- expire := client.Expire("key", 10*time.Second)
- Expect(expire.Err()).NotTo(HaveOccurred())
- Expect(expire.Val()).To(Equal(true))
-
- ttl := client.TTL("key")
- Expect(ttl.Err()).NotTo(HaveOccurred())
- Expect(ttl.Val()).To(Equal(10 * time.Second))
-
- set = client.Set("key", "Hello World", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- ttl = client.TTL("key")
- Expect(ttl.Err()).NotTo(HaveOccurred())
- Expect(ttl.Val() < 0).To(Equal(true))
- })
-
- It("should ExpireAt", func() {
- set := client.Set("key", "Hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- n, err := client.Exists("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(1)))
-
- expireAt := client.ExpireAt("key", time.Now().Add(-time.Hour))
- Expect(expireAt.Err()).NotTo(HaveOccurred())
- Expect(expireAt.Val()).To(Equal(true))
-
- n, err = client.Exists("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(0)))
- })
-
- It("should Keys", func() {
- mset := client.MSet("one", "1", "two", "2", "three", "3", "four", "4")
- Expect(mset.Err()).NotTo(HaveOccurred())
- Expect(mset.Val()).To(Equal("OK"))
-
- keys := client.Keys("*o*")
- Expect(keys.Err()).NotTo(HaveOccurred())
- Expect(keys.Val()).To(ConsistOf([]string{"four", "one", "two"}))
-
- keys = client.Keys("t??")
- Expect(keys.Err()).NotTo(HaveOccurred())
- Expect(keys.Val()).To(Equal([]string{"two"}))
-
- keys = client.Keys("*")
- Expect(keys.Err()).NotTo(HaveOccurred())
- Expect(keys.Val()).To(ConsistOf([]string{"four", "one", "three", "two"}))
- })
-
- It("should Migrate", func() {
- migrate := client.Migrate("localhost", redisSecondaryPort, "key", 0, 0)
- Expect(migrate.Err()).NotTo(HaveOccurred())
- Expect(migrate.Val()).To(Equal("NOKEY"))
-
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- migrate = client.Migrate("localhost", redisSecondaryPort, "key", 0, 0)
- Expect(migrate.Err()).To(MatchError("IOERR error or timeout writing to target instance"))
- Expect(migrate.Val()).To(Equal(""))
- })
-
- It("should Move", func() {
- move := client.Move("key", 2)
- Expect(move.Err()).NotTo(HaveOccurred())
- Expect(move.Val()).To(Equal(false))
-
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- move = client.Move("key", 2)
- Expect(move.Err()).NotTo(HaveOccurred())
- Expect(move.Val()).To(Equal(true))
-
- get := client.Get("key")
- Expect(get.Err()).To(Equal(redis.Nil))
- Expect(get.Val()).To(Equal(""))
-
- pipe := client.Pipeline()
- pipe.Select(2)
- get = pipe.Get("key")
- pipe.FlushDB()
-
- _, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("hello"))
- })
-
- It("should Object", func() {
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- refCount := client.ObjectRefCount("key")
- Expect(refCount.Err()).NotTo(HaveOccurred())
- Expect(refCount.Val()).To(Equal(int64(1)))
-
- err := client.ObjectEncoding("key").Err()
- Expect(err).NotTo(HaveOccurred())
-
- idleTime := client.ObjectIdleTime("key")
- Expect(idleTime.Err()).NotTo(HaveOccurred())
- Expect(idleTime.Val()).To(Equal(time.Duration(0)))
- })
-
- It("should Persist", func() {
- set := client.Set("key", "Hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- expire := client.Expire("key", 10*time.Second)
- Expect(expire.Err()).NotTo(HaveOccurred())
- Expect(expire.Val()).To(Equal(true))
-
- ttl := client.TTL("key")
- Expect(ttl.Err()).NotTo(HaveOccurred())
- Expect(ttl.Val()).To(Equal(10 * time.Second))
-
- persist := client.Persist("key")
- Expect(persist.Err()).NotTo(HaveOccurred())
- Expect(persist.Val()).To(Equal(true))
-
- ttl = client.TTL("key")
- Expect(ttl.Err()).NotTo(HaveOccurred())
- Expect(ttl.Val() < 0).To(Equal(true))
- })
-
- It("should PExpire", func() {
- set := client.Set("key", "Hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- expiration := 900 * time.Millisecond
- pexpire := client.PExpire("key", expiration)
- Expect(pexpire.Err()).NotTo(HaveOccurred())
- Expect(pexpire.Val()).To(Equal(true))
-
- ttl := client.TTL("key")
- Expect(ttl.Err()).NotTo(HaveOccurred())
- Expect(ttl.Val()).To(Equal(time.Second))
-
- pttl := client.PTTL("key")
- Expect(pttl.Err()).NotTo(HaveOccurred())
- Expect(pttl.Val()).To(BeNumerically("~", expiration, 10*time.Millisecond))
- })
-
- It("should PExpireAt", func() {
- set := client.Set("key", "Hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- expiration := 900 * time.Millisecond
- pexpireat := client.PExpireAt("key", time.Now().Add(expiration))
- Expect(pexpireat.Err()).NotTo(HaveOccurred())
- Expect(pexpireat.Val()).To(Equal(true))
-
- ttl := client.TTL("key")
- Expect(ttl.Err()).NotTo(HaveOccurred())
- Expect(ttl.Val()).To(Equal(time.Second))
-
- pttl := client.PTTL("key")
- Expect(pttl.Err()).NotTo(HaveOccurred())
- Expect(pttl.Val()).To(BeNumerically("~", expiration, 10*time.Millisecond))
- })
-
- It("should PTTL", func() {
- set := client.Set("key", "Hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- expiration := time.Second
- expire := client.Expire("key", expiration)
- Expect(expire.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- pttl := client.PTTL("key")
- Expect(pttl.Err()).NotTo(HaveOccurred())
- Expect(pttl.Val()).To(BeNumerically("~", expiration, 10*time.Millisecond))
- })
-
- It("should RandomKey", func() {
- randomKey := client.RandomKey()
- Expect(randomKey.Err()).To(Equal(redis.Nil))
- Expect(randomKey.Val()).To(Equal(""))
-
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- randomKey = client.RandomKey()
- Expect(randomKey.Err()).NotTo(HaveOccurred())
- Expect(randomKey.Val()).To(Equal("key"))
- })
-
- It("should Rename", func() {
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- status := client.Rename("key", "key1")
- Expect(status.Err()).NotTo(HaveOccurred())
- Expect(status.Val()).To(Equal("OK"))
-
- get := client.Get("key1")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("hello"))
- })
-
- It("should RenameNX", func() {
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- renameNX := client.RenameNX("key", "key1")
- Expect(renameNX.Err()).NotTo(HaveOccurred())
- Expect(renameNX.Val()).To(Equal(true))
-
- get := client.Get("key1")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("hello"))
- })
-
- It("should Restore", func() {
- err := client.Set("key", "hello", 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- dump := client.Dump("key")
- Expect(dump.Err()).NotTo(HaveOccurred())
-
- err = client.Del("key").Err()
- Expect(err).NotTo(HaveOccurred())
-
- restore, err := client.Restore("key", 0, dump.Val()).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(restore).To(Equal("OK"))
-
- type_, err := client.Type("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(type_).To(Equal("string"))
-
- val, err := client.Get("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("hello"))
- })
-
- It("should RestoreReplace", func() {
- err := client.Set("key", "hello", 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- dump := client.Dump("key")
- Expect(dump.Err()).NotTo(HaveOccurred())
-
- restore, err := client.RestoreReplace("key", 0, dump.Val()).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(restore).To(Equal("OK"))
-
- type_, err := client.Type("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(type_).To(Equal("string"))
-
- val, err := client.Get("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("hello"))
- })
-
- It("should Sort", func() {
- size, err := client.LPush("list", "1").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(size).To(Equal(int64(1)))
-
- size, err = client.LPush("list", "3").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(size).To(Equal(int64(2)))
-
- size, err = client.LPush("list", "2").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(size).To(Equal(int64(3)))
-
- els, err := client.Sort("list", redis.Sort{
- Offset: 0,
- Count: 2,
- Order: "ASC",
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(els).To(Equal([]string{"1", "2"}))
- })
-
- It("should Sort and Get", func() {
- size, err := client.LPush("list", "1").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(size).To(Equal(int64(1)))
-
- size, err = client.LPush("list", "3").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(size).To(Equal(int64(2)))
-
- size, err = client.LPush("list", "2").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(size).To(Equal(int64(3)))
-
- err = client.Set("object_2", "value2", 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- {
- els, err := client.Sort("list", redis.Sort{
- Get: []string{"object_*"},
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(els).To(Equal([]string{"", "value2", ""}))
- }
-
- {
- els, err := client.SortInterfaces("list", redis.Sort{
- Get: []string{"object_*"},
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(els).To(Equal([]interface{}{nil, "value2", nil}))
- }
- })
-
- It("should TTL", func() {
- ttl := client.TTL("key")
- Expect(ttl.Err()).NotTo(HaveOccurred())
- Expect(ttl.Val() < 0).To(Equal(true))
-
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- expire := client.Expire("key", 60*time.Second)
- Expect(expire.Err()).NotTo(HaveOccurred())
- Expect(expire.Val()).To(Equal(true))
-
- ttl = client.TTL("key")
- Expect(ttl.Err()).NotTo(HaveOccurred())
- Expect(ttl.Val()).To(Equal(60 * time.Second))
- })
-
- It("should Type", func() {
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- type_ := client.Type("key")
- Expect(type_.Err()).NotTo(HaveOccurred())
- Expect(type_.Val()).To(Equal("string"))
- })
-
- })
-
- Describe("scanning", func() {
-
- It("should Scan", func() {
- for i := 0; i < 1000; i++ {
- set := client.Set(fmt.Sprintf("key%d", i), "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- }
-
- keys, cursor, err := client.Scan(0, "", 0).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(keys).NotTo(BeEmpty())
- Expect(cursor).NotTo(BeZero())
- })
-
- It("should SScan", func() {
- for i := 0; i < 1000; i++ {
- sadd := client.SAdd("myset", fmt.Sprintf("member%d", i))
- Expect(sadd.Err()).NotTo(HaveOccurred())
- }
-
- keys, cursor, err := client.SScan("myset", 0, "", 0).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(keys).NotTo(BeEmpty())
- Expect(cursor).NotTo(BeZero())
- })
-
- It("should HScan", func() {
- for i := 0; i < 1000; i++ {
- sadd := client.HSet("myhash", fmt.Sprintf("key%d", i), "hello")
- Expect(sadd.Err()).NotTo(HaveOccurred())
- }
-
- keys, cursor, err := client.HScan("myhash", 0, "", 0).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(keys).NotTo(BeEmpty())
- Expect(cursor).NotTo(BeZero())
- })
-
- It("should ZScan", func() {
- for i := 0; i < 1000; i++ {
- sadd := client.ZAdd("myset", redis.Z{float64(i), fmt.Sprintf("member%d", i)})
- Expect(sadd.Err()).NotTo(HaveOccurred())
- }
-
- keys, cursor, err := client.ZScan("myset", 0, "", 0).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(keys).NotTo(BeEmpty())
- Expect(cursor).NotTo(BeZero())
- })
-
- })
-
- Describe("strings", func() {
-
- It("should Append", func() {
- n, err := client.Exists("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(0)))
-
- append := client.Append("key", "Hello")
- Expect(append.Err()).NotTo(HaveOccurred())
- Expect(append.Val()).To(Equal(int64(5)))
-
- append = client.Append("key", " World")
- Expect(append.Err()).NotTo(HaveOccurred())
- Expect(append.Val()).To(Equal(int64(11)))
-
- get := client.Get("key")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("Hello World"))
- })
-
- It("should BitCount", func() {
- set := client.Set("key", "foobar", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- bitCount := client.BitCount("key", nil)
- Expect(bitCount.Err()).NotTo(HaveOccurred())
- Expect(bitCount.Val()).To(Equal(int64(26)))
-
- bitCount = client.BitCount("key", &redis.BitCount{0, 0})
- Expect(bitCount.Err()).NotTo(HaveOccurred())
- Expect(bitCount.Val()).To(Equal(int64(4)))
-
- bitCount = client.BitCount("key", &redis.BitCount{1, 1})
- Expect(bitCount.Err()).NotTo(HaveOccurred())
- Expect(bitCount.Val()).To(Equal(int64(6)))
- })
-
- It("should BitOpAnd", func() {
- set := client.Set("key1", "1", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- set = client.Set("key2", "0", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- bitOpAnd := client.BitOpAnd("dest", "key1", "key2")
- Expect(bitOpAnd.Err()).NotTo(HaveOccurred())
- Expect(bitOpAnd.Val()).To(Equal(int64(1)))
-
- get := client.Get("dest")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("0"))
- })
-
- It("should BitOpOr", func() {
- set := client.Set("key1", "1", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- set = client.Set("key2", "0", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- bitOpOr := client.BitOpOr("dest", "key1", "key2")
- Expect(bitOpOr.Err()).NotTo(HaveOccurred())
- Expect(bitOpOr.Val()).To(Equal(int64(1)))
-
- get := client.Get("dest")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("1"))
- })
-
- It("should BitOpXor", func() {
- set := client.Set("key1", "\xff", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- set = client.Set("key2", "\x0f", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- bitOpXor := client.BitOpXor("dest", "key1", "key2")
- Expect(bitOpXor.Err()).NotTo(HaveOccurred())
- Expect(bitOpXor.Val()).To(Equal(int64(1)))
-
- get := client.Get("dest")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("\xf0"))
- })
-
- It("should BitOpNot", func() {
- set := client.Set("key1", "\x00", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- bitOpNot := client.BitOpNot("dest", "key1")
- Expect(bitOpNot.Err()).NotTo(HaveOccurred())
- Expect(bitOpNot.Val()).To(Equal(int64(1)))
-
- get := client.Get("dest")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("\xff"))
- })
-
- It("should BitPos", func() {
- err := client.Set("mykey", "\xff\xf0\x00", 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- pos, err := client.BitPos("mykey", 0).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(pos).To(Equal(int64(12)))
-
- pos, err = client.BitPos("mykey", 1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(pos).To(Equal(int64(0)))
-
- pos, err = client.BitPos("mykey", 0, 2).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(pos).To(Equal(int64(16)))
-
- pos, err = client.BitPos("mykey", 1, 2).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(pos).To(Equal(int64(-1)))
-
- pos, err = client.BitPos("mykey", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(pos).To(Equal(int64(16)))
-
- pos, err = client.BitPos("mykey", 1, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(pos).To(Equal(int64(-1)))
-
- pos, err = client.BitPos("mykey", 0, 2, 1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(pos).To(Equal(int64(-1)))
-
- pos, err = client.BitPos("mykey", 0, 0, -3).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(pos).To(Equal(int64(-1)))
-
- pos, err = client.BitPos("mykey", 0, 0, 0).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(pos).To(Equal(int64(-1)))
- })
-
- It("should Decr", func() {
- set := client.Set("key", "10", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- decr := client.Decr("key")
- Expect(decr.Err()).NotTo(HaveOccurred())
- Expect(decr.Val()).To(Equal(int64(9)))
-
- set = client.Set("key", "234293482390480948029348230948", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- decr = client.Decr("key")
- Expect(decr.Err()).To(MatchError("ERR value is not an integer or out of range"))
- Expect(decr.Val()).To(Equal(int64(0)))
- })
-
- It("should DecrBy", func() {
- set := client.Set("key", "10", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- decrBy := client.DecrBy("key", 5)
- Expect(decrBy.Err()).NotTo(HaveOccurred())
- Expect(decrBy.Val()).To(Equal(int64(5)))
- })
-
- It("should Get", func() {
- get := client.Get("_")
- Expect(get.Err()).To(Equal(redis.Nil))
- Expect(get.Val()).To(Equal(""))
-
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- get = client.Get("key")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("hello"))
- })
-
- It("should GetBit", func() {
- setBit := client.SetBit("key", 7, 1)
- Expect(setBit.Err()).NotTo(HaveOccurred())
- Expect(setBit.Val()).To(Equal(int64(0)))
-
- getBit := client.GetBit("key", 0)
- Expect(getBit.Err()).NotTo(HaveOccurred())
- Expect(getBit.Val()).To(Equal(int64(0)))
-
- getBit = client.GetBit("key", 7)
- Expect(getBit.Err()).NotTo(HaveOccurred())
- Expect(getBit.Val()).To(Equal(int64(1)))
-
- getBit = client.GetBit("key", 100)
- Expect(getBit.Err()).NotTo(HaveOccurred())
- Expect(getBit.Val()).To(Equal(int64(0)))
- })
-
- It("should GetRange", func() {
- set := client.Set("key", "This is a string", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- getRange := client.GetRange("key", 0, 3)
- Expect(getRange.Err()).NotTo(HaveOccurred())
- Expect(getRange.Val()).To(Equal("This"))
-
- getRange = client.GetRange("key", -3, -1)
- Expect(getRange.Err()).NotTo(HaveOccurred())
- Expect(getRange.Val()).To(Equal("ing"))
-
- getRange = client.GetRange("key", 0, -1)
- Expect(getRange.Err()).NotTo(HaveOccurred())
- Expect(getRange.Val()).To(Equal("This is a string"))
-
- getRange = client.GetRange("key", 10, 100)
- Expect(getRange.Err()).NotTo(HaveOccurred())
- Expect(getRange.Val()).To(Equal("string"))
- })
-
- It("should GetSet", func() {
- incr := client.Incr("key")
- Expect(incr.Err()).NotTo(HaveOccurred())
- Expect(incr.Val()).To(Equal(int64(1)))
-
- getSet := client.GetSet("key", "0")
- Expect(getSet.Err()).NotTo(HaveOccurred())
- Expect(getSet.Val()).To(Equal("1"))
-
- get := client.Get("key")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("0"))
- })
-
- It("should Incr", func() {
- set := client.Set("key", "10", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- incr := client.Incr("key")
- Expect(incr.Err()).NotTo(HaveOccurred())
- Expect(incr.Val()).To(Equal(int64(11)))
-
- get := client.Get("key")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("11"))
- })
-
- It("should IncrBy", func() {
- set := client.Set("key", "10", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- incrBy := client.IncrBy("key", 5)
- Expect(incrBy.Err()).NotTo(HaveOccurred())
- Expect(incrBy.Val()).To(Equal(int64(15)))
- })
-
- It("should IncrByFloat", func() {
- set := client.Set("key", "10.50", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- incrByFloat := client.IncrByFloat("key", 0.1)
- Expect(incrByFloat.Err()).NotTo(HaveOccurred())
- Expect(incrByFloat.Val()).To(Equal(10.6))
-
- set = client.Set("key", "5.0e3", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- incrByFloat = client.IncrByFloat("key", 2.0e2)
- Expect(incrByFloat.Err()).NotTo(HaveOccurred())
- Expect(incrByFloat.Val()).To(Equal(float64(5200)))
- })
-
- It("should IncrByFloatOverflow", func() {
- incrByFloat := client.IncrByFloat("key", 996945661)
- Expect(incrByFloat.Err()).NotTo(HaveOccurred())
- Expect(incrByFloat.Val()).To(Equal(float64(996945661)))
- })
-
- It("should MSetMGet", func() {
- mSet := client.MSet("key1", "hello1", "key2", "hello2")
- Expect(mSet.Err()).NotTo(HaveOccurred())
- Expect(mSet.Val()).To(Equal("OK"))
-
- mGet := client.MGet("key1", "key2", "_")
- Expect(mGet.Err()).NotTo(HaveOccurred())
- Expect(mGet.Val()).To(Equal([]interface{}{"hello1", "hello2", nil}))
- })
-
- It("should MSetNX", func() {
- mSetNX := client.MSetNX("key1", "hello1", "key2", "hello2")
- Expect(mSetNX.Err()).NotTo(HaveOccurred())
- Expect(mSetNX.Val()).To(Equal(true))
-
- mSetNX = client.MSetNX("key2", "hello1", "key3", "hello2")
- Expect(mSetNX.Err()).NotTo(HaveOccurred())
- Expect(mSetNX.Val()).To(Equal(false))
- })
-
- It("should Set with expiration", func() {
- err := client.Set("key", "hello", 100*time.Millisecond).Err()
- Expect(err).NotTo(HaveOccurred())
-
- val, err := client.Get("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("hello"))
-
- Eventually(func() error {
- return client.Get("foo").Err()
- }, "1s", "100ms").Should(Equal(redis.Nil))
- })
-
- It("should SetGet", func() {
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- get := client.Get("key")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("hello"))
- })
-
- It("should SetNX", func() {
- setNX := client.SetNX("key", "hello", 0)
- Expect(setNX.Err()).NotTo(HaveOccurred())
- Expect(setNX.Val()).To(Equal(true))
-
- setNX = client.SetNX("key", "hello2", 0)
- Expect(setNX.Err()).NotTo(HaveOccurred())
- Expect(setNX.Val()).To(Equal(false))
-
- get := client.Get("key")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("hello"))
- })
-
- It("should SetNX with expiration", func() {
- isSet, err := client.SetNX("key", "hello", time.Second).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(isSet).To(Equal(true))
-
- isSet, err = client.SetNX("key", "hello2", time.Second).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(isSet).To(Equal(false))
-
- val, err := client.Get("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("hello"))
- })
-
- It("should SetXX", func() {
- isSet, err := client.SetXX("key", "hello2", 0).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(isSet).To(Equal(false))
-
- err = client.Set("key", "hello", 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- isSet, err = client.SetXX("key", "hello2", 0).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(isSet).To(Equal(true))
-
- val, err := client.Get("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("hello2"))
- })
-
- It("should SetXX with expiration", func() {
- isSet, err := client.SetXX("key", "hello2", time.Second).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(isSet).To(Equal(false))
-
- err = client.Set("key", "hello", time.Second).Err()
- Expect(err).NotTo(HaveOccurred())
-
- isSet, err = client.SetXX("key", "hello2", time.Second).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(isSet).To(Equal(true))
-
- val, err := client.Get("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("hello2"))
- })
-
- It("should SetRange", func() {
- set := client.Set("key", "Hello World", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- range_ := client.SetRange("key", 6, "Redis")
- Expect(range_.Err()).NotTo(HaveOccurred())
- Expect(range_.Val()).To(Equal(int64(11)))
-
- get := client.Get("key")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("Hello Redis"))
- })
-
- It("should StrLen", func() {
- set := client.Set("key", "hello", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- strLen := client.StrLen("key")
- Expect(strLen.Err()).NotTo(HaveOccurred())
- Expect(strLen.Val()).To(Equal(int64(5)))
-
- strLen = client.StrLen("_")
- Expect(strLen.Err()).NotTo(HaveOccurred())
- Expect(strLen.Val()).To(Equal(int64(0)))
- })
-
- })
-
- Describe("hashes", func() {
-
- It("should HDel", func() {
- hSet := client.HSet("hash", "key", "hello")
- Expect(hSet.Err()).NotTo(HaveOccurred())
-
- hDel := client.HDel("hash", "key")
- Expect(hDel.Err()).NotTo(HaveOccurred())
- Expect(hDel.Val()).To(Equal(int64(1)))
-
- hDel = client.HDel("hash", "key")
- Expect(hDel.Err()).NotTo(HaveOccurred())
- Expect(hDel.Val()).To(Equal(int64(0)))
- })
-
- It("should HExists", func() {
- hSet := client.HSet("hash", "key", "hello")
- Expect(hSet.Err()).NotTo(HaveOccurred())
-
- hExists := client.HExists("hash", "key")
- Expect(hExists.Err()).NotTo(HaveOccurred())
- Expect(hExists.Val()).To(Equal(true))
-
- hExists = client.HExists("hash", "key1")
- Expect(hExists.Err()).NotTo(HaveOccurred())
- Expect(hExists.Val()).To(Equal(false))
- })
-
- It("should HGet", func() {
- hSet := client.HSet("hash", "key", "hello")
- Expect(hSet.Err()).NotTo(HaveOccurred())
-
- hGet := client.HGet("hash", "key")
- Expect(hGet.Err()).NotTo(HaveOccurred())
- Expect(hGet.Val()).To(Equal("hello"))
-
- hGet = client.HGet("hash", "key1")
- Expect(hGet.Err()).To(Equal(redis.Nil))
- Expect(hGet.Val()).To(Equal(""))
- })
-
- It("should HGetAll", func() {
- err := client.HSet("hash", "key1", "hello1").Err()
- Expect(err).NotTo(HaveOccurred())
- err = client.HSet("hash", "key2", "hello2").Err()
- Expect(err).NotTo(HaveOccurred())
-
- m, err := client.HGetAll("hash").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(m).To(Equal(map[string]string{"key1": "hello1", "key2": "hello2"}))
- })
-
- It("should HIncrBy", func() {
- hSet := client.HSet("hash", "key", "5")
- Expect(hSet.Err()).NotTo(HaveOccurred())
-
- hIncrBy := client.HIncrBy("hash", "key", 1)
- Expect(hIncrBy.Err()).NotTo(HaveOccurred())
- Expect(hIncrBy.Val()).To(Equal(int64(6)))
-
- hIncrBy = client.HIncrBy("hash", "key", -1)
- Expect(hIncrBy.Err()).NotTo(HaveOccurred())
- Expect(hIncrBy.Val()).To(Equal(int64(5)))
-
- hIncrBy = client.HIncrBy("hash", "key", -10)
- Expect(hIncrBy.Err()).NotTo(HaveOccurred())
- Expect(hIncrBy.Val()).To(Equal(int64(-5)))
- })
-
- It("should HIncrByFloat", func() {
- hSet := client.HSet("hash", "field", "10.50")
- Expect(hSet.Err()).NotTo(HaveOccurred())
- Expect(hSet.Val()).To(Equal(true))
-
- hIncrByFloat := client.HIncrByFloat("hash", "field", 0.1)
- Expect(hIncrByFloat.Err()).NotTo(HaveOccurred())
- Expect(hIncrByFloat.Val()).To(Equal(10.6))
-
- hSet = client.HSet("hash", "field", "5.0e3")
- Expect(hSet.Err()).NotTo(HaveOccurred())
- Expect(hSet.Val()).To(Equal(false))
-
- hIncrByFloat = client.HIncrByFloat("hash", "field", 2.0e2)
- Expect(hIncrByFloat.Err()).NotTo(HaveOccurred())
- Expect(hIncrByFloat.Val()).To(Equal(float64(5200)))
- })
-
- It("should HKeys", func() {
- hkeys := client.HKeys("hash")
- Expect(hkeys.Err()).NotTo(HaveOccurred())
- Expect(hkeys.Val()).To(Equal([]string{}))
-
- hset := client.HSet("hash", "key1", "hello1")
- Expect(hset.Err()).NotTo(HaveOccurred())
- hset = client.HSet("hash", "key2", "hello2")
- Expect(hset.Err()).NotTo(HaveOccurred())
-
- hkeys = client.HKeys("hash")
- Expect(hkeys.Err()).NotTo(HaveOccurred())
- Expect(hkeys.Val()).To(Equal([]string{"key1", "key2"}))
- })
-
- It("should HLen", func() {
- hSet := client.HSet("hash", "key1", "hello1")
- Expect(hSet.Err()).NotTo(HaveOccurred())
- hSet = client.HSet("hash", "key2", "hello2")
- Expect(hSet.Err()).NotTo(HaveOccurred())
-
- hLen := client.HLen("hash")
- Expect(hLen.Err()).NotTo(HaveOccurred())
- Expect(hLen.Val()).To(Equal(int64(2)))
- })
-
- It("should HMGet", func() {
- err := client.HSet("hash", "key1", "hello1").Err()
- Expect(err).NotTo(HaveOccurred())
- err = client.HSet("hash", "key2", "hello2").Err()
- Expect(err).NotTo(HaveOccurred())
-
- vals, err := client.HMGet("hash", "key1", "key2", "_").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]interface{}{"hello1", "hello2", nil}))
- })
-
- It("should HMSet", func() {
- ok, err := client.HMSet("hash", map[string]interface{}{
- "key1": "hello1",
- "key2": "hello2",
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(ok).To(Equal("OK"))
-
- v, err := client.HGet("hash", "key1").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(v).To(Equal("hello1"))
-
- v, err = client.HGet("hash", "key2").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(v).To(Equal("hello2"))
- })
-
- It("should HSet", func() {
- hSet := client.HSet("hash", "key", "hello")
- Expect(hSet.Err()).NotTo(HaveOccurred())
- Expect(hSet.Val()).To(Equal(true))
-
- hGet := client.HGet("hash", "key")
- Expect(hGet.Err()).NotTo(HaveOccurred())
- Expect(hGet.Val()).To(Equal("hello"))
- })
-
- It("should HSetNX", func() {
- hSetNX := client.HSetNX("hash", "key", "hello")
- Expect(hSetNX.Err()).NotTo(HaveOccurred())
- Expect(hSetNX.Val()).To(Equal(true))
-
- hSetNX = client.HSetNX("hash", "key", "hello")
- Expect(hSetNX.Err()).NotTo(HaveOccurred())
- Expect(hSetNX.Val()).To(Equal(false))
-
- hGet := client.HGet("hash", "key")
- Expect(hGet.Err()).NotTo(HaveOccurred())
- Expect(hGet.Val()).To(Equal("hello"))
- })
-
- It("should HVals", func() {
- err := client.HSet("hash", "key1", "hello1").Err()
- Expect(err).NotTo(HaveOccurred())
- err = client.HSet("hash", "key2", "hello2").Err()
- Expect(err).NotTo(HaveOccurred())
-
- v, err := client.HVals("hash").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(v).To(Equal([]string{"hello1", "hello2"}))
-
- var slice []string
- err = client.HVals("hash").ScanSlice(&slice)
- Expect(err).NotTo(HaveOccurred())
- Expect(slice).To(Equal([]string{"hello1", "hello2"}))
- })
-
- })
-
- Describe("hyperloglog", func() {
- It("should PFMerge", func() {
- pfAdd := client.PFAdd("hll1", "1", "2", "3", "4", "5")
- Expect(pfAdd.Err()).NotTo(HaveOccurred())
-
- pfCount := client.PFCount("hll1")
- Expect(pfCount.Err()).NotTo(HaveOccurred())
- Expect(pfCount.Val()).To(Equal(int64(5)))
-
- pfAdd = client.PFAdd("hll2", "a", "b", "c", "d", "e")
- Expect(pfAdd.Err()).NotTo(HaveOccurred())
-
- pfMerge := client.PFMerge("hllMerged", "hll1", "hll2")
- Expect(pfMerge.Err()).NotTo(HaveOccurred())
-
- pfCount = client.PFCount("hllMerged")
- Expect(pfCount.Err()).NotTo(HaveOccurred())
- Expect(pfCount.Val()).To(Equal(int64(10)))
-
- pfCount = client.PFCount("hll1", "hll2")
- Expect(pfCount.Err()).NotTo(HaveOccurred())
- Expect(pfCount.Val()).To(Equal(int64(10)))
- })
- })
-
- Describe("lists", func() {
-
- It("should BLPop", func() {
- rPush := client.RPush("list1", "a", "b", "c")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- bLPop := client.BLPop(0, "list1", "list2")
- Expect(bLPop.Err()).NotTo(HaveOccurred())
- Expect(bLPop.Val()).To(Equal([]string{"list1", "a"}))
- })
-
- It("should BLPopBlocks", func() {
- started := make(chan bool)
- done := make(chan bool)
- go func() {
- defer GinkgoRecover()
-
- started <- true
- bLPop := client.BLPop(0, "list")
- Expect(bLPop.Err()).NotTo(HaveOccurred())
- Expect(bLPop.Val()).To(Equal([]string{"list", "a"}))
- done <- true
- }()
- <-started
-
- select {
- case <-done:
- Fail("BLPop is not blocked")
- case <-time.After(time.Second):
- // ok
- }
-
- rPush := client.RPush("list", "a")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- select {
- case <-done:
- // ok
- case <-time.After(time.Second):
- Fail("BLPop is still blocked")
- }
- })
-
- It("should BLPop timeout", func() {
- val, err := client.BLPop(time.Second, "list1").Result()
- Expect(err).To(Equal(redis.Nil))
- Expect(val).To(BeNil())
-
- Expect(client.Ping().Err()).NotTo(HaveOccurred())
-
- stats := client.PoolStats()
- Expect(stats.Hits).To(Equal(uint32(1)))
- Expect(stats.Misses).To(Equal(uint32(2)))
- Expect(stats.Timeouts).To(Equal(uint32(0)))
- })
-
- It("should BRPop", func() {
- rPush := client.RPush("list1", "a", "b", "c")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- bRPop := client.BRPop(0, "list1", "list2")
- Expect(bRPop.Err()).NotTo(HaveOccurred())
- Expect(bRPop.Val()).To(Equal([]string{"list1", "c"}))
- })
-
- It("should BRPop blocks", func() {
- started := make(chan bool)
- done := make(chan bool)
- go func() {
- defer GinkgoRecover()
-
- started <- true
- brpop := client.BRPop(0, "list")
- Expect(brpop.Err()).NotTo(HaveOccurred())
- Expect(brpop.Val()).To(Equal([]string{"list", "a"}))
- done <- true
- }()
- <-started
-
- select {
- case <-done:
- Fail("BRPop is not blocked")
- case <-time.After(time.Second):
- // ok
- }
-
- rPush := client.RPush("list", "a")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- select {
- case <-done:
- // ok
- case <-time.After(time.Second):
- Fail("BRPop is still blocked")
- // ok
- }
- })
-
- It("should BRPopLPush", func() {
- _, err := client.BRPopLPush("list1", "list2", time.Second).Result()
- Expect(err).To(Equal(redis.Nil))
-
- err = client.RPush("list1", "a", "b", "c").Err()
- Expect(err).NotTo(HaveOccurred())
-
- v, err := client.BRPopLPush("list1", "list2", 0).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(v).To(Equal("c"))
- })
-
- It("should LIndex", func() {
- lPush := client.LPush("list", "World")
- Expect(lPush.Err()).NotTo(HaveOccurred())
- lPush = client.LPush("list", "Hello")
- Expect(lPush.Err()).NotTo(HaveOccurred())
-
- lIndex := client.LIndex("list", 0)
- Expect(lIndex.Err()).NotTo(HaveOccurred())
- Expect(lIndex.Val()).To(Equal("Hello"))
-
- lIndex = client.LIndex("list", -1)
- Expect(lIndex.Err()).NotTo(HaveOccurred())
- Expect(lIndex.Val()).To(Equal("World"))
-
- lIndex = client.LIndex("list", 3)
- Expect(lIndex.Err()).To(Equal(redis.Nil))
- Expect(lIndex.Val()).To(Equal(""))
- })
-
- It("should LInsert", func() {
- rPush := client.RPush("list", "Hello")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "World")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- lInsert := client.LInsert("list", "BEFORE", "World", "There")
- Expect(lInsert.Err()).NotTo(HaveOccurred())
- Expect(lInsert.Val()).To(Equal(int64(3)))
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"Hello", "There", "World"}))
- })
-
- It("should LLen", func() {
- lPush := client.LPush("list", "World")
- Expect(lPush.Err()).NotTo(HaveOccurred())
- lPush = client.LPush("list", "Hello")
- Expect(lPush.Err()).NotTo(HaveOccurred())
-
- lLen := client.LLen("list")
- Expect(lLen.Err()).NotTo(HaveOccurred())
- Expect(lLen.Val()).To(Equal(int64(2)))
- })
-
- It("should LPop", func() {
- rPush := client.RPush("list", "one")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "two")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "three")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- lPop := client.LPop("list")
- Expect(lPop.Err()).NotTo(HaveOccurred())
- Expect(lPop.Val()).To(Equal("one"))
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"two", "three"}))
- })
-
- It("should LPush", func() {
- lPush := client.LPush("list", "World")
- Expect(lPush.Err()).NotTo(HaveOccurred())
- lPush = client.LPush("list", "Hello")
- Expect(lPush.Err()).NotTo(HaveOccurred())
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
- })
-
- It("should LPushX", func() {
- lPush := client.LPush("list", "World")
- Expect(lPush.Err()).NotTo(HaveOccurred())
-
- lPushX := client.LPushX("list", "Hello")
- Expect(lPushX.Err()).NotTo(HaveOccurred())
- Expect(lPushX.Val()).To(Equal(int64(2)))
-
- lPushX = client.LPushX("list2", "Hello")
- Expect(lPushX.Err()).NotTo(HaveOccurred())
- Expect(lPushX.Val()).To(Equal(int64(0)))
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
-
- lRange = client.LRange("list2", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{}))
- })
-
- It("should LRange", func() {
- rPush := client.RPush("list", "one")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "two")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "three")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- lRange := client.LRange("list", 0, 0)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"one"}))
-
- lRange = client.LRange("list", -3, 2)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"one", "two", "three"}))
-
- lRange = client.LRange("list", -100, 100)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"one", "two", "three"}))
-
- lRange = client.LRange("list", 5, 10)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{}))
- })
-
- It("should LRem", func() {
- rPush := client.RPush("list", "hello")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "hello")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "key")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "hello")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- lRem := client.LRem("list", -2, "hello")
- Expect(lRem.Err()).NotTo(HaveOccurred())
- Expect(lRem.Val()).To(Equal(int64(2)))
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"hello", "key"}))
- })
-
- It("should LSet", func() {
- rPush := client.RPush("list", "one")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "two")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "three")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- lSet := client.LSet("list", 0, "four")
- Expect(lSet.Err()).NotTo(HaveOccurred())
- Expect(lSet.Val()).To(Equal("OK"))
-
- lSet = client.LSet("list", -2, "five")
- Expect(lSet.Err()).NotTo(HaveOccurred())
- Expect(lSet.Val()).To(Equal("OK"))
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"four", "five", "three"}))
- })
-
- It("should LTrim", func() {
- rPush := client.RPush("list", "one")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "two")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "three")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- lTrim := client.LTrim("list", 1, -1)
- Expect(lTrim.Err()).NotTo(HaveOccurred())
- Expect(lTrim.Val()).To(Equal("OK"))
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"two", "three"}))
- })
-
- It("should RPop", func() {
- rPush := client.RPush("list", "one")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "two")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "three")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- rPop := client.RPop("list")
- Expect(rPop.Err()).NotTo(HaveOccurred())
- Expect(rPop.Val()).To(Equal("three"))
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"one", "two"}))
- })
-
- It("should RPopLPush", func() {
- rPush := client.RPush("list", "one")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "two")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- rPush = client.RPush("list", "three")
- Expect(rPush.Err()).NotTo(HaveOccurred())
-
- rPopLPush := client.RPopLPush("list", "list2")
- Expect(rPopLPush.Err()).NotTo(HaveOccurred())
- Expect(rPopLPush.Val()).To(Equal("three"))
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"one", "two"}))
-
- lRange = client.LRange("list2", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"three"}))
- })
-
- It("should RPush", func() {
- rPush := client.RPush("list", "Hello")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- Expect(rPush.Val()).To(Equal(int64(1)))
-
- rPush = client.RPush("list", "World")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- Expect(rPush.Val()).To(Equal(int64(2)))
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
- })
-
- It("should RPushX", func() {
- rPush := client.RPush("list", "Hello")
- Expect(rPush.Err()).NotTo(HaveOccurred())
- Expect(rPush.Val()).To(Equal(int64(1)))
-
- rPushX := client.RPushX("list", "World")
- Expect(rPushX.Err()).NotTo(HaveOccurred())
- Expect(rPushX.Val()).To(Equal(int64(2)))
-
- rPushX = client.RPushX("list2", "World")
- Expect(rPushX.Err()).NotTo(HaveOccurred())
- Expect(rPushX.Val()).To(Equal(int64(0)))
-
- lRange := client.LRange("list", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{"Hello", "World"}))
-
- lRange = client.LRange("list2", 0, -1)
- Expect(lRange.Err()).NotTo(HaveOccurred())
- Expect(lRange.Val()).To(Equal([]string{}))
- })
-
- })
-
- Describe("sets", func() {
-
- It("should SAdd", func() {
- sAdd := client.SAdd("set", "Hello")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- Expect(sAdd.Val()).To(Equal(int64(1)))
-
- sAdd = client.SAdd("set", "World")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- Expect(sAdd.Val()).To(Equal(int64(1)))
-
- sAdd = client.SAdd("set", "World")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- Expect(sAdd.Val()).To(Equal(int64(0)))
-
- sMembers := client.SMembers("set")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- Expect(sMembers.Val()).To(ConsistOf([]string{"Hello", "World"}))
- })
-
- It("should SCard", func() {
- sAdd := client.SAdd("set", "Hello")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- Expect(sAdd.Val()).To(Equal(int64(1)))
-
- sAdd = client.SAdd("set", "World")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- Expect(sAdd.Val()).To(Equal(int64(1)))
-
- sCard := client.SCard("set")
- Expect(sCard.Err()).NotTo(HaveOccurred())
- Expect(sCard.Val()).To(Equal(int64(2)))
- })
-
- It("should SDiff", func() {
- sAdd := client.SAdd("set1", "a")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "b")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sAdd = client.SAdd("set2", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "d")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "e")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sDiff := client.SDiff("set1", "set2")
- Expect(sDiff.Err()).NotTo(HaveOccurred())
- Expect(sDiff.Val()).To(ConsistOf([]string{"a", "b"}))
- })
-
- It("should SDiffStore", func() {
- sAdd := client.SAdd("set1", "a")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "b")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sAdd = client.SAdd("set2", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "d")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "e")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sDiffStore := client.SDiffStore("set", "set1", "set2")
- Expect(sDiffStore.Err()).NotTo(HaveOccurred())
- Expect(sDiffStore.Val()).To(Equal(int64(2)))
-
- sMembers := client.SMembers("set")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- Expect(sMembers.Val()).To(ConsistOf([]string{"a", "b"}))
- })
-
- It("should SInter", func() {
- sAdd := client.SAdd("set1", "a")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "b")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sAdd = client.SAdd("set2", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "d")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "e")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sInter := client.SInter("set1", "set2")
- Expect(sInter.Err()).NotTo(HaveOccurred())
- Expect(sInter.Val()).To(Equal([]string{"c"}))
- })
-
- It("should SInterStore", func() {
- sAdd := client.SAdd("set1", "a")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "b")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sAdd = client.SAdd("set2", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "d")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "e")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sInterStore := client.SInterStore("set", "set1", "set2")
- Expect(sInterStore.Err()).NotTo(HaveOccurred())
- Expect(sInterStore.Val()).To(Equal(int64(1)))
-
- sMembers := client.SMembers("set")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- Expect(sMembers.Val()).To(Equal([]string{"c"}))
- })
-
- It("should IsMember", func() {
- sAdd := client.SAdd("set", "one")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sIsMember := client.SIsMember("set", "one")
- Expect(sIsMember.Err()).NotTo(HaveOccurred())
- Expect(sIsMember.Val()).To(Equal(true))
-
- sIsMember = client.SIsMember("set", "two")
- Expect(sIsMember.Err()).NotTo(HaveOccurred())
- Expect(sIsMember.Val()).To(Equal(false))
- })
-
- It("should SMembers", func() {
- sAdd := client.SAdd("set", "Hello")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set", "World")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sMembers := client.SMembers("set")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- 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())
- sAdd = client.SAdd("set1", "two")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sAdd = client.SAdd("set2", "three")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sMove := client.SMove("set1", "set2", "two")
- Expect(sMove.Err()).NotTo(HaveOccurred())
- Expect(sMove.Val()).To(Equal(true))
-
- sMembers := client.SMembers("set1")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- Expect(sMembers.Val()).To(Equal([]string{"one"}))
-
- sMembers = client.SMembers("set2")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- Expect(sMembers.Val()).To(ConsistOf([]string{"three", "two"}))
- })
-
- It("should SPop", func() {
- sAdd := client.SAdd("set", "one")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set", "two")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set", "three")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sPop := client.SPop("set")
- Expect(sPop.Err()).NotTo(HaveOccurred())
- Expect(sPop.Val()).NotTo(Equal(""))
-
- sMembers := client.SMembers("set")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- Expect(sMembers.Val()).To(HaveLen(2))
-
- })
-
- It("should SPopN", func() {
- sAdd := client.SAdd("set", "one")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set", "two")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set", "three")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set", "four")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sPopN := client.SPopN("set", 1)
- Expect(sPopN.Err()).NotTo(HaveOccurred())
- Expect(sPopN.Val()).NotTo(Equal([]string{""}))
-
- sMembers := client.SMembers("set")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- Expect(sMembers.Val()).To(HaveLen(3))
-
- sPopN = client.SPopN("set", 4)
- Expect(sPopN.Err()).NotTo(HaveOccurred())
- Expect(sPopN.Val()).To(HaveLen(3))
-
- sMembers = client.SMembers("set")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- Expect(sMembers.Val()).To(HaveLen(0))
- })
-
- It("should SRandMember and SRandMemberN", func() {
- err := client.SAdd("set", "one").Err()
- Expect(err).NotTo(HaveOccurred())
- err = client.SAdd("set", "two").Err()
- Expect(err).NotTo(HaveOccurred())
- err = client.SAdd("set", "three").Err()
- Expect(err).NotTo(HaveOccurred())
-
- members, err := client.SMembers("set").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(members).To(HaveLen(3))
-
- member, err := client.SRandMember("set").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(member).NotTo(Equal(""))
-
- members, err = client.SRandMemberN("set", 2).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(members).To(HaveLen(2))
- })
-
- It("should SRem", func() {
- sAdd := client.SAdd("set", "one")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set", "two")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set", "three")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sRem := client.SRem("set", "one")
- Expect(sRem.Err()).NotTo(HaveOccurred())
- Expect(sRem.Val()).To(Equal(int64(1)))
-
- sRem = client.SRem("set", "four")
- Expect(sRem.Err()).NotTo(HaveOccurred())
- Expect(sRem.Val()).To(Equal(int64(0)))
-
- sMembers := client.SMembers("set")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- Expect(sMembers.Val()).To(ConsistOf([]string{"three", "two"}))
- })
-
- It("should SUnion", func() {
- sAdd := client.SAdd("set1", "a")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "b")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sAdd = client.SAdd("set2", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "d")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "e")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sUnion := client.SUnion("set1", "set2")
- Expect(sUnion.Err()).NotTo(HaveOccurred())
- Expect(sUnion.Val()).To(HaveLen(5))
- })
-
- It("should SUnionStore", func() {
- sAdd := client.SAdd("set1", "a")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "b")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set1", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sAdd = client.SAdd("set2", "c")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "d")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
- sAdd = client.SAdd("set2", "e")
- Expect(sAdd.Err()).NotTo(HaveOccurred())
-
- sUnionStore := client.SUnionStore("set", "set1", "set2")
- Expect(sUnionStore.Err()).NotTo(HaveOccurred())
- Expect(sUnionStore.Val()).To(Equal(int64(5)))
-
- sMembers := client.SMembers("set")
- Expect(sMembers.Err()).NotTo(HaveOccurred())
- Expect(sMembers.Val()).To(HaveLen(5))
- })
-
- })
-
- Describe("sorted sets", func() {
-
- It("should ZAdd", func() {
- added, err := client.ZAdd("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(1)))
-
- added, err = client.ZAdd("zset", redis.Z{1, "uno"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(1)))
-
- added, err = client.ZAdd("zset", redis.Z{2, "two"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(1)))
-
- added, err = client.ZAdd("zset", redis.Z{3, "two"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(0)))
-
- vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{1, "one"}, {1, "uno"}, {3, "two"}}))
- })
-
- It("should ZAdd bytes", func() {
- added, err := client.ZAdd("zset", redis.Z{1, []byte("one")}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(1)))
-
- added, err = client.ZAdd("zset", redis.Z{1, []byte("uno")}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(1)))
-
- added, err = client.ZAdd("zset", redis.Z{2, []byte("two")}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(1)))
-
- added, err = client.ZAdd("zset", redis.Z{3, []byte("two")}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(0)))
-
- val, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{1, "one"}, {1, "uno"}, {3, "two"}}))
- })
-
- It("should ZAddNX", func() {
- added, err := client.ZAddNX("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(1)))
-
- vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
-
- added, err = client.ZAddNX("zset", redis.Z{2, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(0)))
-
- vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
- })
-
- It("should ZAddXX", func() {
- added, err := client.ZAddXX("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(0)))
-
- vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(BeEmpty())
-
- added, err = client.ZAdd("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(1)))
-
- added, err = client.ZAddXX("zset", redis.Z{2, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(0)))
-
- vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{2, "one"}}))
- })
-
- It("should ZAddCh", func() {
- changed, err := client.ZAddCh("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(changed).To(Equal(int64(1)))
-
- changed, err = client.ZAddCh("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(changed).To(Equal(int64(0)))
- })
-
- It("should ZAddNXCh", func() {
- changed, err := client.ZAddNXCh("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(changed).To(Equal(int64(1)))
-
- vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
-
- changed, err = client.ZAddNXCh("zset", redis.Z{2, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(changed).To(Equal(int64(0)))
-
- vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
- })
-
- It("should ZAddXXCh", func() {
- changed, err := client.ZAddXXCh("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(changed).To(Equal(int64(0)))
-
- vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(BeEmpty())
-
- added, err := client.ZAdd("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(1)))
-
- changed, err = client.ZAddXXCh("zset", redis.Z{2, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(changed).To(Equal(int64(1)))
-
- vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{2, "one"}}))
- })
-
- It("should ZIncr", func() {
- score, err := client.ZIncr("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(score).To(Equal(float64(1)))
-
- vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
-
- score, err = client.ZIncr("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(score).To(Equal(float64(2)))
-
- vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{2, "one"}}))
- })
-
- It("should ZIncrNX", func() {
- score, err := client.ZIncrNX("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(score).To(Equal(float64(1)))
-
- vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
-
- score, err = client.ZIncrNX("zset", redis.Z{1, "one"}).Result()
- Expect(err).To(Equal(redis.Nil))
- Expect(score).To(Equal(float64(0)))
-
- vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{1, "one"}}))
- })
-
- It("should ZIncrXX", func() {
- score, err := client.ZIncrXX("zset", redis.Z{1, "one"}).Result()
- Expect(err).To(Equal(redis.Nil))
- Expect(score).To(Equal(float64(0)))
-
- vals, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(BeEmpty())
-
- added, err := client.ZAdd("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(added).To(Equal(int64(1)))
-
- score, err = client.ZIncrXX("zset", redis.Z{1, "one"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(score).To(Equal(float64(2)))
-
- vals, err = client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{2, "one"}}))
- })
-
- It("should ZCard", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zCard := client.ZCard("zset")
- Expect(zCard.Err()).NotTo(HaveOccurred())
- Expect(zCard.Val()).To(Equal(int64(2)))
- })
-
- It("should ZCount", func() {
- err := client.ZAdd("zset", redis.Z{1, "one"}).Err()
- Expect(err).NotTo(HaveOccurred())
- err = client.ZAdd("zset", redis.Z{2, "two"}).Err()
- Expect(err).NotTo(HaveOccurred())
- err = client.ZAdd("zset", redis.Z{3, "three"}).Err()
- Expect(err).NotTo(HaveOccurred())
-
- count, err := client.ZCount("zset", "-inf", "+inf").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(count).To(Equal(int64(3)))
-
- count, err = client.ZCount("zset", "(1", "3").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(count).To(Equal(int64(2)))
-
- count, err = client.ZLexCount("zset", "-", "+").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(count).To(Equal(int64(3)))
- })
-
- It("should ZIncrBy", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zIncrBy := client.ZIncrBy("zset", 2, "one")
- Expect(zIncrBy.Err()).NotTo(HaveOccurred())
- Expect(zIncrBy.Val()).To(Equal(float64(3)))
-
- val, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{2, "two"}, {3, "one"}}))
- })
-
- It("should ZInterStore", func() {
- zAdd := client.ZAdd("zset1", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset1", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zAdd = client.ZAdd("zset2", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset2", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset3", redis.Z{3, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zInterStore := client.ZInterStore(
- "out", redis.ZStore{Weights: []float64{2, 3}}, "zset1", "zset2")
- Expect(zInterStore.Err()).NotTo(HaveOccurred())
- Expect(zInterStore.Val()).To(Equal(int64(2)))
-
- val, err := client.ZRangeWithScores("out", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{5, "one"}, {10, "two"}}))
- })
-
- It("should ZRange", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zRange := client.ZRange("zset", 0, -1)
- Expect(zRange.Err()).NotTo(HaveOccurred())
- Expect(zRange.Val()).To(Equal([]string{"one", "two", "three"}))
-
- zRange = client.ZRange("zset", 2, 3)
- Expect(zRange.Err()).NotTo(HaveOccurred())
- Expect(zRange.Val()).To(Equal([]string{"three"}))
-
- zRange = client.ZRange("zset", -2, -1)
- Expect(zRange.Err()).NotTo(HaveOccurred())
- Expect(zRange.Val()).To(Equal([]string{"two", "three"}))
- })
-
- It("should ZRangeWithScores", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- val, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{1, "one"}, {2, "two"}, {3, "three"}}))
-
- val, err = client.ZRangeWithScores("zset", 2, 3).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{3, "three"}}))
-
- val, err = client.ZRangeWithScores("zset", -2, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{2, "two"}, {3, "three"}}))
- })
-
- It("should ZRangeByScore", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zRangeByScore := client.ZRangeByScore("zset", redis.ZRangeBy{
- Min: "-inf",
- Max: "+inf",
- })
- Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
- Expect(zRangeByScore.Val()).To(Equal([]string{"one", "two", "three"}))
-
- zRangeByScore = client.ZRangeByScore("zset", redis.ZRangeBy{
- Min: "1",
- Max: "2",
- })
- Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
- Expect(zRangeByScore.Val()).To(Equal([]string{"one", "two"}))
-
- zRangeByScore = client.ZRangeByScore("zset", redis.ZRangeBy{
- Min: "(1",
- Max: "2",
- })
- Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
- Expect(zRangeByScore.Val()).To(Equal([]string{"two"}))
-
- zRangeByScore = client.ZRangeByScore("zset", redis.ZRangeBy{
- Min: "(1",
- Max: "(2",
- })
- Expect(zRangeByScore.Err()).NotTo(HaveOccurred())
- Expect(zRangeByScore.Val()).To(Equal([]string{}))
- })
-
- It("should ZRangeByLex", func() {
- zAdd := client.ZAdd("zset", redis.Z{0, "a"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{0, "b"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{0, "c"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zRangeByLex := client.ZRangeByLex("zset", redis.ZRangeBy{
- Min: "-",
- Max: "+",
- })
- Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
- Expect(zRangeByLex.Val()).To(Equal([]string{"a", "b", "c"}))
-
- zRangeByLex = client.ZRangeByLex("zset", redis.ZRangeBy{
- Min: "[a",
- Max: "[b",
- })
- Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
- Expect(zRangeByLex.Val()).To(Equal([]string{"a", "b"}))
-
- zRangeByLex = client.ZRangeByLex("zset", redis.ZRangeBy{
- Min: "(a",
- Max: "[b",
- })
- Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
- Expect(zRangeByLex.Val()).To(Equal([]string{"b"}))
-
- zRangeByLex = client.ZRangeByLex("zset", redis.ZRangeBy{
- Min: "(a",
- Max: "(b",
- })
- Expect(zRangeByLex.Err()).NotTo(HaveOccurred())
- Expect(zRangeByLex.Val()).To(Equal([]string{}))
- })
-
- It("should ZRangeByScoreWithScoresMap", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- val, err := client.ZRangeByScoreWithScores("zset", redis.ZRangeBy{
- Min: "-inf",
- Max: "+inf",
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{1, "one"}, {2, "two"}, {3, "three"}}))
-
- val, err = client.ZRangeByScoreWithScores("zset", redis.ZRangeBy{
- Min: "1",
- Max: "2",
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{1, "one"}, {2, "two"}}))
-
- val, err = client.ZRangeByScoreWithScores("zset", redis.ZRangeBy{
- Min: "(1",
- Max: "2",
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{2, "two"}}))
-
- val, err = client.ZRangeByScoreWithScores("zset", redis.ZRangeBy{
- Min: "(1",
- Max: "(2",
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{}))
- })
-
- It("should ZRank", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zRank := client.ZRank("zset", "three")
- Expect(zRank.Err()).NotTo(HaveOccurred())
- Expect(zRank.Val()).To(Equal(int64(2)))
-
- zRank = client.ZRank("zset", "four")
- Expect(zRank.Err()).To(Equal(redis.Nil))
- Expect(zRank.Val()).To(Equal(int64(0)))
- })
-
- It("should ZRem", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zRem := client.ZRem("zset", "two")
- Expect(zRem.Err()).NotTo(HaveOccurred())
- Expect(zRem.Val()).To(Equal(int64(1)))
-
- val, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{1, "one"}, {3, "three"}}))
- })
-
- It("should ZRemRangeByRank", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zRemRangeByRank := client.ZRemRangeByRank("zset", 0, 1)
- Expect(zRemRangeByRank.Err()).NotTo(HaveOccurred())
- Expect(zRemRangeByRank.Val()).To(Equal(int64(2)))
-
- val, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{3, "three"}}))
- })
-
- It("should ZRemRangeByScore", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zRemRangeByScore := client.ZRemRangeByScore("zset", "-inf", "(2")
- Expect(zRemRangeByScore.Err()).NotTo(HaveOccurred())
- Expect(zRemRangeByScore.Val()).To(Equal(int64(1)))
-
- val, err := client.ZRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{2, "two"}, {3, "three"}}))
- })
-
- It("should ZRemRangeByLex", func() {
- zz := []redis.Z{
- {0, "aaaa"},
- {0, "b"},
- {0, "c"},
- {0, "d"},
- {0, "e"},
- {0, "foo"},
- {0, "zap"},
- {0, "zip"},
- {0, "ALPHA"},
- {0, "alpha"},
- }
- for _, z := range zz {
- err := client.ZAdd("zset", z).Err()
- Expect(err).NotTo(HaveOccurred())
- }
-
- n, err := client.ZRemRangeByLex("zset", "[alpha", "[omega").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(6)))
-
- vals, err := client.ZRange("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]string{"ALPHA", "aaaa", "zap", "zip"}))
- })
-
- It("should ZRevRange", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zRevRange := client.ZRevRange("zset", 0, -1)
- Expect(zRevRange.Err()).NotTo(HaveOccurred())
- Expect(zRevRange.Val()).To(Equal([]string{"three", "two", "one"}))
-
- zRevRange = client.ZRevRange("zset", 2, 3)
- Expect(zRevRange.Err()).NotTo(HaveOccurred())
- Expect(zRevRange.Val()).To(Equal([]string{"one"}))
-
- zRevRange = client.ZRevRange("zset", -2, -1)
- Expect(zRevRange.Err()).NotTo(HaveOccurred())
- Expect(zRevRange.Val()).To(Equal([]string{"two", "one"}))
- })
-
- It("should ZRevRangeWithScoresMap", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- val, err := client.ZRevRangeWithScores("zset", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{3, "three"}, {2, "two"}, {1, "one"}}))
-
- val, err = client.ZRevRangeWithScores("zset", 2, 3).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{1, "one"}}))
-
- val, err = client.ZRevRangeWithScores("zset", -2, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{2, "two"}, {1, "one"}}))
- })
-
- It("should ZRevRangeByScore", func() {
- zadd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zadd.Err()).NotTo(HaveOccurred())
- zadd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zadd.Err()).NotTo(HaveOccurred())
- zadd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zadd.Err()).NotTo(HaveOccurred())
-
- vals, err := client.ZRevRangeByScore(
- "zset", redis.ZRangeBy{Max: "+inf", Min: "-inf"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]string{"three", "two", "one"}))
-
- vals, err = client.ZRevRangeByScore(
- "zset", redis.ZRangeBy{Max: "2", Min: "(1"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]string{"two"}))
-
- vals, err = client.ZRevRangeByScore(
- "zset", redis.ZRangeBy{Max: "(2", Min: "(1"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]string{}))
- })
-
- It("should ZRevRangeByLex", func() {
- zadd := client.ZAdd("zset", redis.Z{0, "a"})
- Expect(zadd.Err()).NotTo(HaveOccurred())
- zadd = client.ZAdd("zset", redis.Z{0, "b"})
- Expect(zadd.Err()).NotTo(HaveOccurred())
- zadd = client.ZAdd("zset", redis.Z{0, "c"})
- Expect(zadd.Err()).NotTo(HaveOccurred())
-
- vals, err := client.ZRevRangeByLex(
- "zset", redis.ZRangeBy{Max: "+", Min: "-"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]string{"c", "b", "a"}))
-
- vals, err = client.ZRevRangeByLex(
- "zset", redis.ZRangeBy{Max: "[b", Min: "(a"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]string{"b"}))
-
- vals, err = client.ZRevRangeByLex(
- "zset", redis.ZRangeBy{Max: "(b", Min: "(a"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]string{}))
- })
-
- It("should ZRevRangeByScoreWithScores", func() {
- zadd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zadd.Err()).NotTo(HaveOccurred())
- zadd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zadd.Err()).NotTo(HaveOccurred())
- zadd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zadd.Err()).NotTo(HaveOccurred())
-
- vals, err := client.ZRevRangeByScoreWithScores(
- "zset", redis.ZRangeBy{Max: "+inf", Min: "-inf"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]redis.Z{{3, "three"}, {2, "two"}, {1, "one"}}))
- })
-
- It("should ZRevRangeByScoreWithScoresMap", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- val, err := client.ZRevRangeByScoreWithScores(
- "zset", redis.ZRangeBy{Max: "+inf", Min: "-inf"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{3, "three"}, {2, "two"}, {1, "one"}}))
-
- val, err = client.ZRevRangeByScoreWithScores(
- "zset", redis.ZRangeBy{Max: "2", Min: "(1"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{2, "two"}}))
-
- val, err = client.ZRevRangeByScoreWithScores(
- "zset", redis.ZRangeBy{Max: "(2", Min: "(1"}).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{}))
- })
-
- It("should ZRevRank", func() {
- zAdd := client.ZAdd("zset", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zRevRank := client.ZRevRank("zset", "one")
- Expect(zRevRank.Err()).NotTo(HaveOccurred())
- Expect(zRevRank.Val()).To(Equal(int64(2)))
-
- zRevRank = client.ZRevRank("zset", "four")
- Expect(zRevRank.Err()).To(Equal(redis.Nil))
- Expect(zRevRank.Val()).To(Equal(int64(0)))
- })
-
- It("should ZScore", func() {
- zAdd := client.ZAdd("zset", redis.Z{1.001, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zScore := client.ZScore("zset", "one")
- Expect(zScore.Err()).NotTo(HaveOccurred())
- Expect(zScore.Val()).To(Equal(float64(1.001)))
- })
-
- It("should ZUnionStore", func() {
- zAdd := client.ZAdd("zset1", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset1", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zAdd = client.ZAdd("zset2", redis.Z{1, "one"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset2", redis.Z{2, "two"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
- zAdd = client.ZAdd("zset2", redis.Z{3, "three"})
- Expect(zAdd.Err()).NotTo(HaveOccurred())
-
- zUnionStore := client.ZUnionStore(
- "out", redis.ZStore{Weights: []float64{2, 3}}, "zset1", "zset2")
- Expect(zUnionStore.Err()).NotTo(HaveOccurred())
- Expect(zUnionStore.Val()).To(Equal(int64(3)))
-
- val, err := client.ZRangeWithScores("out", 0, -1).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal([]redis.Z{{5, "one"}, {9, "three"}, {10, "two"}}))
- })
-
- })
-
- Describe("Geo add and radius search", func() {
- BeforeEach(func() {
- geoAdd := client.GeoAdd(
- "Sicily",
- &redis.GeoLocation{Longitude: 13.361389, Latitude: 38.115556, Name: "Palermo"},
- &redis.GeoLocation{Longitude: 15.087269, Latitude: 37.502669, Name: "Catania"},
- )
- Expect(geoAdd.Err()).NotTo(HaveOccurred())
- Expect(geoAdd.Val()).To(Equal(int64(2)))
- })
-
- It("should not add same geo location", func() {
- geoAdd := client.GeoAdd(
- "Sicily",
- &redis.GeoLocation{Longitude: 13.361389, Latitude: 38.115556, Name: "Palermo"},
- )
- Expect(geoAdd.Err()).NotTo(HaveOccurred())
- Expect(geoAdd.Val()).To(Equal(int64(0)))
- })
-
- It("should search geo radius", func() {
- res, err := client.GeoRadius("Sicily", 15, 37, &redis.GeoRadiusQuery{
- Radius: 200,
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(res).To(HaveLen(2))
- Expect(res[0].Name).To(Equal("Palermo"))
- Expect(res[1].Name).To(Equal("Catania"))
- })
-
- It("should search geo radius with options", func() {
- res, err := client.GeoRadius("Sicily", 15, 37, &redis.GeoRadiusQuery{
- Radius: 200,
- Unit: "km",
- WithGeoHash: true,
- WithCoord: true,
- WithDist: true,
- Count: 2,
- Sort: "ASC",
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(res).To(HaveLen(2))
- Expect(res[1].Name).To(Equal("Palermo"))
- Expect(res[1].Dist).To(Equal(190.4424))
- Expect(res[1].GeoHash).To(Equal(int64(3479099956230698)))
- Expect(res[1].Longitude).To(Equal(13.361389338970184))
- Expect(res[1].Latitude).To(Equal(38.115556395496299))
- Expect(res[0].Name).To(Equal("Catania"))
- Expect(res[0].Dist).To(Equal(56.4413))
- Expect(res[0].GeoHash).To(Equal(int64(3479447370796909)))
- Expect(res[0].Longitude).To(Equal(15.087267458438873))
- Expect(res[0].Latitude).To(Equal(37.50266842333162))
- })
-
- It("should search geo radius with WithDist=false", func() {
- res, err := client.GeoRadius("Sicily", 15, 37, &redis.GeoRadiusQuery{
- Radius: 200,
- Unit: "km",
- WithGeoHash: true,
- WithCoord: true,
- Count: 2,
- Sort: "ASC",
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(res).To(HaveLen(2))
- Expect(res[1].Name).To(Equal("Palermo"))
- Expect(res[1].Dist).To(Equal(float64(0)))
- Expect(res[1].GeoHash).To(Equal(int64(3479099956230698)))
- Expect(res[1].Longitude).To(Equal(13.361389338970184))
- Expect(res[1].Latitude).To(Equal(38.115556395496299))
- Expect(res[0].Name).To(Equal("Catania"))
- Expect(res[0].Dist).To(Equal(float64(0)))
- Expect(res[0].GeoHash).To(Equal(int64(3479447370796909)))
- Expect(res[0].Longitude).To(Equal(15.087267458438873))
- Expect(res[0].Latitude).To(Equal(37.50266842333162))
- })
-
- It("should search geo radius by member with options", func() {
- res, err := client.GeoRadiusByMember("Sicily", "Catania", &redis.GeoRadiusQuery{
- Radius: 200,
- Unit: "km",
- WithGeoHash: true,
- WithCoord: true,
- WithDist: true,
- Count: 2,
- Sort: "ASC",
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(res).To(HaveLen(2))
- Expect(res[0].Name).To(Equal("Catania"))
- Expect(res[0].Dist).To(Equal(0.0))
- Expect(res[0].GeoHash).To(Equal(int64(3479447370796909)))
- Expect(res[0].Longitude).To(Equal(15.087267458438873))
- Expect(res[0].Latitude).To(Equal(37.50266842333162))
- Expect(res[1].Name).To(Equal("Palermo"))
- Expect(res[1].Dist).To(Equal(166.2742))
- Expect(res[1].GeoHash).To(Equal(int64(3479099956230698)))
- Expect(res[1].Longitude).To(Equal(13.361389338970184))
- Expect(res[1].Latitude).To(Equal(38.115556395496299))
- })
-
- It("should search geo radius with no results", func() {
- res, err := client.GeoRadius("Sicily", 99, 37, &redis.GeoRadiusQuery{
- Radius: 200,
- Unit: "km",
- WithGeoHash: true,
- WithCoord: true,
- WithDist: true,
- }).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(res).To(HaveLen(0))
- })
-
- It("should get geo distance with unit options", func() {
- // From Redis CLI, note the difference in rounding in m vs
- // km on Redis itself.
- //
- // GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
- // GEODIST Sicily Palermo Catania m
- // "166274.15156960033"
- // GEODIST Sicily Palermo Catania km
- // "166.27415156960032"
- dist, err := client.GeoDist("Sicily", "Palermo", "Catania", "km").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(dist).To(BeNumerically("~", 166.27, 0.01))
-
- dist, err = client.GeoDist("Sicily", "Palermo", "Catania", "m").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(dist).To(BeNumerically("~", 166274.15, 0.01))
- })
-
- It("should get geo hash in string representation", func() {
- hashes, err := client.GeoHash("Sicily", "Palermo", "Catania").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(hashes).To(ConsistOf([]string{"sqc8b49rny0", "sqdtr74hyu0"}))
- })
-
- It("should return geo position", func() {
- pos, err := client.GeoPos("Sicily", "Palermo", "Catania", "NonExisting").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(pos).To(ConsistOf([]*redis.GeoPos{
- {
- Longitude: 13.361389338970184,
- Latitude: 38.1155563954963,
- },
- {
- Longitude: 15.087267458438873,
- Latitude: 37.50266842333162,
- },
- nil,
- }))
- })
- })
-
- Describe("marshaling/unmarshaling", func() {
-
- type convTest struct {
- value interface{}
- wanted string
- dest interface{}
- }
-
- convTests := []convTest{
- {nil, "", nil},
- {"hello", "hello", new(string)},
- {[]byte("hello"), "hello", new([]byte)},
- {int(1), "1", new(int)},
- {int8(1), "1", new(int8)},
- {int16(1), "1", new(int16)},
- {int32(1), "1", new(int32)},
- {int64(1), "1", new(int64)},
- {uint(1), "1", new(uint)},
- {uint8(1), "1", new(uint8)},
- {uint16(1), "1", new(uint16)},
- {uint32(1), "1", new(uint32)},
- {uint64(1), "1", new(uint64)},
- {float32(1.0), "1", new(float32)},
- {float64(1.0), "1", new(float64)},
- {true, "1", new(bool)},
- {false, "0", new(bool)},
- }
-
- It("should convert to string", func() {
- for _, test := range convTests {
- err := client.Set("key", test.value, 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- s, err := client.Get("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(s).To(Equal(test.wanted))
-
- if test.dest == nil {
- continue
- }
-
- err = client.Get("key").Scan(test.dest)
- Expect(err).NotTo(HaveOccurred())
- Expect(deref(test.dest)).To(Equal(test.value))
- }
- })
-
- })
-
- Describe("json marshaling/unmarshaling", func() {
-
- BeforeEach(func() {
- value := &numberStruct{Number: 42}
- err := client.Set("key", value, 0).Err()
- Expect(err).NotTo(HaveOccurred())
- })
-
- It("should marshal custom values using json", func() {
- s, err := client.Get("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(s).To(Equal(`{"Number":42}`))
- })
-
- It("should scan custom values using json", func() {
- value := &numberStruct{}
- err := client.Get("key").Scan(value)
- Expect(err).NotTo(HaveOccurred())
- Expect(value.Number).To(Equal(42))
- })
-
- })
-
- Describe("Eval", func() {
-
- It("returns keys and values", func() {
- vals, err := client.Eval(
- "return {KEYS[1],ARGV[1]}",
- []string{"key"},
- "hello",
- ).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(vals).To(Equal([]interface{}{"key", "hello"}))
- })
-
- })
-
-})
-
-type numberStruct struct {
- Number int
-}
-
-func (s *numberStruct) MarshalBinary() ([]byte, error) {
- return json.Marshal(s)
-}
-
-func (s *numberStruct) UnmarshalBinary(b []byte) error {
- return json.Unmarshal(b, s)
-}
-
-func deref(viface interface{}) interface{} {
- v := reflect.ValueOf(viface)
- for v.Kind() == reflect.Ptr {
- v = v.Elem()
- }
- return v.Interface()
-}
diff --git a/vendor/github.com/go-redis/redis/example_instrumentation_test.go b/vendor/github.com/go-redis/redis/example_instrumentation_test.go
deleted file mode 100644
index 85abbd744..000000000
--- a/vendor/github.com/go-redis/redis/example_instrumentation_test.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package redis_test
-
-import (
- "fmt"
-
- "github.com/go-redis/redis"
-)
-
-func Example_instrumentation() {
- cl := redis.NewClient(&redis.Options{
- Addr: ":6379",
- })
- cl.WrapProcess(func(old func(cmd redis.Cmder) error) func(cmd redis.Cmder) error {
- return func(cmd redis.Cmder) error {
- fmt.Printf("starting processing: <%s>\n", cmd)
- err := old(cmd)
- fmt.Printf("finished processing: <%s>\n", cmd)
- return err
- }
- })
-
- cl.Ping()
- // Output: starting processing: <ping: >
- // finished processing: <ping: PONG>
-}
-
-func Example_Pipeline_instrumentation() {
- client := redis.NewClient(&redis.Options{
- Addr: ":6379",
- })
-
- client.WrapProcessPipeline(func(old func([]redis.Cmder) error) func([]redis.Cmder) error {
- return func(cmds []redis.Cmder) error {
- fmt.Printf("pipeline starting processing: %v\n", cmds)
- err := old(cmds)
- fmt.Printf("pipeline finished processing: %v\n", cmds)
- return err
- }
- })
-
- client.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Ping()
- pipe.Ping()
- return nil
- })
- // Output: pipeline starting processing: [ping: ping: ]
- // pipeline finished processing: [ping: PONG ping: PONG]
-}
diff --git a/vendor/github.com/go-redis/redis/example_test.go b/vendor/github.com/go-redis/redis/example_test.go
deleted file mode 100644
index 4d18ddb94..000000000
--- a/vendor/github.com/go-redis/redis/example_test.go
+++ /dev/null
@@ -1,414 +0,0 @@
-package redis_test
-
-import (
- "fmt"
- "strconv"
- "sync"
- "time"
-
- "github.com/go-redis/redis"
-)
-
-var client *redis.Client
-
-func init() {
- client = redis.NewClient(&redis.Options{
- Addr: ":6379",
- DialTimeout: 10 * time.Second,
- ReadTimeout: 30 * time.Second,
- WriteTimeout: 30 * time.Second,
- PoolSize: 10,
- PoolTimeout: 30 * time.Second,
- })
- client.FlushDB()
-}
-
-func ExampleNewClient() {
- client := redis.NewClient(&redis.Options{
- Addr: "localhost:6379",
- Password: "", // no password set
- DB: 0, // use default DB
- })
-
- pong, err := client.Ping().Result()
- fmt.Println(pong, err)
- // Output: PONG <nil>
-}
-
-func ExampleParseURL() {
- opt, err := redis.ParseURL("redis://:qwerty@localhost:6379/1")
- if err != nil {
- panic(err)
- }
- fmt.Println("addr is", opt.Addr)
- fmt.Println("db is", opt.DB)
- fmt.Println("password is", opt.Password)
-
- // Create client as usually.
- _ = redis.NewClient(opt)
-
- // Output: addr is localhost:6379
- // db is 1
- // password is qwerty
-}
-
-func ExampleNewFailoverClient() {
- // See http://redis.io/topics/sentinel for instructions how to
- // setup Redis Sentinel.
- client := redis.NewFailoverClient(&redis.FailoverOptions{
- MasterName: "master",
- SentinelAddrs: []string{":26379"},
- })
- client.Ping()
-}
-
-func ExampleNewClusterClient() {
- // See http://redis.io/topics/cluster-tutorial for instructions
- // how to setup Redis Cluster.
- client := redis.NewClusterClient(&redis.ClusterOptions{
- Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
- })
- client.Ping()
-}
-
-func ExampleNewRing() {
- client := redis.NewRing(&redis.RingOptions{
- Addrs: map[string]string{
- "shard1": ":7000",
- "shard2": ":7001",
- "shard3": ":7002",
- },
- })
- client.Ping()
-}
-
-func ExampleClient() {
- err := client.Set("key", "value", 0).Err()
- if err != nil {
- panic(err)
- }
-
- val, err := client.Get("key").Result()
- if err != nil {
- panic(err)
- }
- fmt.Println("key", val)
-
- val2, err := client.Get("key2").Result()
- if err == redis.Nil {
- fmt.Println("key2 does not exist")
- } else if err != nil {
- panic(err)
- } else {
- fmt.Println("key2", val2)
- }
- // Output: key value
- // key2 does not exist
-}
-
-func ExampleClient_Set() {
- // Last argument is expiration. Zero means the key has no
- // expiration time.
- err := client.Set("key", "value", 0).Err()
- if err != nil {
- panic(err)
- }
-
- // key2 will expire in an hour.
- err = client.Set("key2", "value", time.Hour).Err()
- if err != nil {
- panic(err)
- }
-}
-
-func ExampleClient_Incr() {
- result, err := client.Incr("counter").Result()
- if err != nil {
- panic(err)
- }
-
- fmt.Println(result)
- // Output: 1
-}
-
-func ExampleClient_BLPop() {
- if err := client.RPush("queue", "message").Err(); err != nil {
- panic(err)
- }
-
- // use `client.BLPop(0, "queue")` for infinite waiting time
- result, err := client.BLPop(1*time.Second, "queue").Result()
- if err != nil {
- panic(err)
- }
-
- fmt.Println(result[0], result[1])
- // Output: queue message
-}
-
-func ExampleClient_Scan() {
- client.FlushDB()
- for i := 0; i < 33; i++ {
- err := client.Set(fmt.Sprintf("key%d", i), "value", 0).Err()
- if err != nil {
- panic(err)
- }
- }
-
- var cursor uint64
- var n int
- for {
- var keys []string
- var err error
- keys, cursor, err = client.Scan(cursor, "", 10).Result()
- if err != nil {
- panic(err)
- }
- n += len(keys)
- if cursor == 0 {
- break
- }
- }
-
- fmt.Printf("found %d keys\n", n)
- // Output: found 33 keys
-}
-
-func ExampleClient_Pipelined() {
- var incr *redis.IntCmd
- _, err := client.Pipelined(func(pipe redis.Pipeliner) error {
- incr = pipe.Incr("pipelined_counter")
- pipe.Expire("pipelined_counter", time.Hour)
- return nil
- })
- fmt.Println(incr.Val(), err)
- // Output: 1 <nil>
-}
-
-func ExampleClient_Pipeline() {
- pipe := client.Pipeline()
-
- incr := pipe.Incr("pipeline_counter")
- pipe.Expire("pipeline_counter", time.Hour)
-
- // Execute
- //
- // INCR pipeline_counter
- // EXPIRE pipeline_counts 3600
- //
- // using one client-server roundtrip.
- _, err := pipe.Exec()
- fmt.Println(incr.Val(), err)
- // Output: 1 <nil>
-}
-
-func ExampleClient_TxPipelined() {
- var incr *redis.IntCmd
- _, err := client.TxPipelined(func(pipe redis.Pipeliner) error {
- incr = pipe.Incr("tx_pipelined_counter")
- pipe.Expire("tx_pipelined_counter", time.Hour)
- return nil
- })
- fmt.Println(incr.Val(), err)
- // Output: 1 <nil>
-}
-
-func ExampleClient_TxPipeline() {
- pipe := client.TxPipeline()
-
- incr := pipe.Incr("tx_pipeline_counter")
- pipe.Expire("tx_pipeline_counter", time.Hour)
-
- // Execute
- //
- // MULTI
- // INCR pipeline_counter
- // EXPIRE pipeline_counts 3600
- // EXEC
- //
- // using one client-server roundtrip.
- _, err := pipe.Exec()
- fmt.Println(incr.Val(), err)
- // Output: 1 <nil>
-}
-
-func ExampleClient_Watch() {
- var incr func(string) error
-
- // Transactionally increments key using GET and SET commands.
- incr = func(key string) error {
- err := client.Watch(func(tx *redis.Tx) error {
- n, err := tx.Get(key).Int64()
- if err != nil && err != redis.Nil {
- return err
- }
-
- _, err = tx.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Set(key, strconv.FormatInt(n+1, 10), 0)
- return nil
- })
- return err
- }, key)
- if err == redis.TxFailedErr {
- return incr(key)
- }
- return err
- }
-
- var wg sync.WaitGroup
- for i := 0; i < 100; i++ {
- wg.Add(1)
- go func() {
- defer wg.Done()
-
- err := incr("counter3")
- if err != nil {
- panic(err)
- }
- }()
- }
- wg.Wait()
-
- n, err := client.Get("counter3").Int64()
- fmt.Println(n, err)
- // Output: 100 <nil>
-}
-
-func ExamplePubSub() {
- pubsub := client.Subscribe("mychannel1")
- defer pubsub.Close()
-
- // Wait for subscription to be created before publishing message.
- subscr, err := pubsub.ReceiveTimeout(time.Second)
- if err != nil {
- panic(err)
- }
- fmt.Println(subscr)
-
- err = client.Publish("mychannel1", "hello").Err()
- if err != nil {
- panic(err)
- }
-
- msg, err := pubsub.ReceiveMessage()
- if err != nil {
- panic(err)
- }
-
- fmt.Println(msg.Channel, msg.Payload)
- // Output: subscribe: mychannel1
- // mychannel1 hello
-}
-
-func ExamplePubSub_Receive() {
- pubsub := client.Subscribe("mychannel2")
- defer pubsub.Close()
-
- for i := 0; i < 2; i++ {
- // ReceiveTimeout is a low level API. Use ReceiveMessage instead.
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- if err != nil {
- break
- }
-
- switch msg := msgi.(type) {
- case *redis.Subscription:
- fmt.Println("subscribed to", msg.Channel)
-
- _, err := client.Publish("mychannel2", "hello").Result()
- if err != nil {
- panic(err)
- }
- case *redis.Message:
- fmt.Println("received", msg.Payload, "from", msg.Channel)
- default:
- panic("unreached")
- }
- }
-
- // sent message to 1 client
- // received hello from mychannel2
-}
-
-func ExampleScript() {
- IncrByXX := redis.NewScript(`
- if redis.call("GET", KEYS[1]) ~= false then
- return redis.call("INCRBY", KEYS[1], ARGV[1])
- end
- return false
- `)
-
- n, err := IncrByXX.Run(client, []string{"xx_counter"}, 2).Result()
- fmt.Println(n, err)
-
- err = client.Set("xx_counter", "40", 0).Err()
- if err != nil {
- panic(err)
- }
-
- n, err = IncrByXX.Run(client, []string{"xx_counter"}, 2).Result()
- fmt.Println(n, err)
-
- // Output: <nil> redis: nil
- // 42 <nil>
-}
-
-func Example_customCommand() {
- Get := func(client *redis.Client, key string) *redis.StringCmd {
- cmd := redis.NewStringCmd("get", key)
- client.Process(cmd)
- return cmd
- }
-
- v, err := Get(client, "key_does_not_exist").Result()
- fmt.Printf("%q %s", v, err)
- // Output: "" redis: nil
-}
-
-func ExampleScanIterator() {
- iter := client.Scan(0, "", 0).Iterator()
- for iter.Next() {
- fmt.Println(iter.Val())
- }
- if err := iter.Err(); err != nil {
- panic(err)
- }
-}
-
-func ExampleScanCmd_Iterator() {
- iter := client.Scan(0, "", 0).Iterator()
- for iter.Next() {
- fmt.Println(iter.Val())
- }
- if err := iter.Err(); err != nil {
- panic(err)
- }
-}
-
-func ExampleNewUniversalClient_simple() {
- client := redis.NewUniversalClient(&redis.UniversalOptions{
- Addrs: []string{":6379"},
- })
- defer client.Close()
-
- client.Ping()
-}
-
-func ExampleNewUniversalClient_failover() {
- client := redis.NewUniversalClient(&redis.UniversalOptions{
- MasterName: "master",
- Addrs: []string{":26379"},
- })
- defer client.Close()
-
- client.Ping()
-}
-
-func ExampleNewUniversalClient_cluster() {
- client := redis.NewUniversalClient(&redis.UniversalOptions{
- Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
- })
- defer client.Close()
-
- client.Ping()
-}
diff --git a/vendor/github.com/go-redis/redis/export_test.go b/vendor/github.com/go-redis/redis/export_test.go
deleted file mode 100644
index bcc18c457..000000000
--- a/vendor/github.com/go-redis/redis/export_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package redis
-
-import (
- "net"
- "time"
-
- "github.com/go-redis/redis/internal/pool"
-)
-
-func (c *baseClient) Pool() pool.Pooler {
- return c.connPool
-}
-
-func (c *PubSub) SetNetConn(netConn net.Conn) {
- c.cn = pool.NewConn(netConn)
-}
-
-func (c *PubSub) ReceiveMessageTimeout(timeout time.Duration) (*Message, error) {
- return c.receiveMessage(timeout)
-}
-
-func (c *ClusterClient) SlotAddrs(slot int) []string {
- state, err := c.state()
- if err != nil {
- panic(err)
- }
-
- var addrs []string
- for _, n := range state.slotNodes(slot) {
- addrs = append(addrs, n.Client.getAddr())
- }
- return addrs
-}
-
-// SwapSlot swaps a slot's master/slave address for testing MOVED redirects.
-func (c *ClusterClient) SwapSlotNodes(slot int) {
- state, err := c.state()
- if err != nil {
- panic(err)
- }
-
- nodes := state.slots[slot]
- if len(nodes) == 2 {
- nodes[0], nodes[1] = nodes[1], nodes[0]
- }
-}
diff --git a/vendor/github.com/go-redis/redis/internal/consistenthash/consistenthash_test.go b/vendor/github.com/go-redis/redis/internal/consistenthash/consistenthash_test.go
deleted file mode 100644
index 1a37fd7ff..000000000
--- a/vendor/github.com/go-redis/redis/internal/consistenthash/consistenthash_test.go
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-Copyright 2013 Google Inc.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package consistenthash
-
-import (
- "fmt"
- "strconv"
- "testing"
-)
-
-func TestHashing(t *testing.T) {
-
- // Override the hash function to return easier to reason about values. Assumes
- // the keys can be converted to an integer.
- hash := New(3, func(key []byte) uint32 {
- i, err := strconv.Atoi(string(key))
- if err != nil {
- panic(err)
- }
- return uint32(i)
- })
-
- // Given the above hash function, this will give replicas with "hashes":
- // 2, 4, 6, 12, 14, 16, 22, 24, 26
- hash.Add("6", "4", "2")
-
- testCases := map[string]string{
- "2": "2",
- "11": "2",
- "23": "4",
- "27": "2",
- }
-
- for k, v := range testCases {
- if hash.Get(k) != v {
- t.Errorf("Asking for %s, should have yielded %s", k, v)
- }
- }
-
- // Adds 8, 18, 28
- hash.Add("8")
-
- // 27 should now map to 8.
- testCases["27"] = "8"
-
- for k, v := range testCases {
- if hash.Get(k) != v {
- t.Errorf("Asking for %s, should have yielded %s", k, v)
- }
- }
-
-}
-
-func TestConsistency(t *testing.T) {
- hash1 := New(1, nil)
- hash2 := New(1, nil)
-
- hash1.Add("Bill", "Bob", "Bonny")
- hash2.Add("Bob", "Bonny", "Bill")
-
- if hash1.Get("Ben") != hash2.Get("Ben") {
- t.Errorf("Fetching 'Ben' from both hashes should be the same")
- }
-
- hash2.Add("Becky", "Ben", "Bobby")
-
- if hash1.Get("Ben") != hash2.Get("Ben") ||
- hash1.Get("Bob") != hash2.Get("Bob") ||
- hash1.Get("Bonny") != hash2.Get("Bonny") {
- t.Errorf("Direct matches should always return the same entry")
- }
-
-}
-
-func BenchmarkGet8(b *testing.B) { benchmarkGet(b, 8) }
-func BenchmarkGet32(b *testing.B) { benchmarkGet(b, 32) }
-func BenchmarkGet128(b *testing.B) { benchmarkGet(b, 128) }
-func BenchmarkGet512(b *testing.B) { benchmarkGet(b, 512) }
-
-func benchmarkGet(b *testing.B, shards int) {
-
- hash := New(50, nil)
-
- var buckets []string
- for i := 0; i < shards; i++ {
- buckets = append(buckets, fmt.Sprintf("shard-%d", i))
- }
-
- hash.Add(buckets...)
-
- b.ResetTimer()
-
- for i := 0; i < b.N; i++ {
- hash.Get(buckets[i&(shards-1)])
- }
-}
diff --git a/vendor/github.com/go-redis/redis/internal/error.go b/vendor/github.com/go-redis/redis/internal/error.go
index 0898eeb62..7b419577e 100644
--- a/vendor/github.com/go-redis/redis/internal/error.go
+++ b/vendor/github.com/go-redis/redis/internal/error.go
@@ -4,13 +4,9 @@ import (
"io"
"net"
"strings"
-)
-
-const Nil = RedisError("redis: nil")
-
-type RedisError string
-func (e RedisError) Error() string { return string(e) }
+ "github.com/go-redis/redis/internal/proto"
+)
func IsRetryableError(err error, retryNetError bool) bool {
if IsNetworkError(err) {
@@ -30,7 +26,7 @@ func IsRetryableError(err error, retryNetError bool) bool {
}
func IsRedisError(err error) bool {
- _, ok := err.(RedisError)
+ _, ok := err.(proto.RedisError)
return ok
}
@@ -42,6 +38,10 @@ func IsNetworkError(err error) bool {
return ok
}
+func IsReadOnlyError(err error) bool {
+ return strings.HasPrefix(err.Error(), "READONLY ")
+}
+
func IsBadConn(err error, allowTimeout bool) bool {
if err == nil {
return false
diff --git a/vendor/github.com/go-redis/redis/internal/hashtag/hashtag_test.go b/vendor/github.com/go-redis/redis/internal/hashtag/hashtag_test.go
deleted file mode 100644
index 7f0fedf31..000000000
--- a/vendor/github.com/go-redis/redis/internal/hashtag/hashtag_test.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package hashtag
-
-import (
- "math/rand"
- "testing"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-func TestGinkgoSuite(t *testing.T) {
- RegisterFailHandler(Fail)
- RunSpecs(t, "hashtag")
-}
-
-var _ = Describe("CRC16", func() {
-
- // http://redis.io/topics/cluster-spec#keys-distribution-model
- It("should calculate CRC16", func() {
- tests := []struct {
- s string
- n uint16
- }{
- {"123456789", 0x31C3},
- {string([]byte{83, 153, 134, 118, 229, 214, 244, 75, 140, 37, 215, 215}), 21847},
- }
-
- for _, test := range tests {
- Expect(crc16sum(test.s)).To(Equal(test.n), "for %s", test.s)
- }
- })
-
-})
-
-var _ = Describe("HashSlot", func() {
-
- It("should calculate hash slots", func() {
- tests := []struct {
- key string
- slot int
- }{
- {"123456789", 12739},
- {"{}foo", 9500},
- {"foo{}", 5542},
- {"foo{}{bar}", 8363},
- {"", 10503},
- {"", 5176},
- {string([]byte{83, 153, 134, 118, 229, 214, 244, 75, 140, 37, 215, 215}), 5463},
- }
- // Empty keys receive random slot.
- rand.Seed(100)
-
- for _, test := range tests {
- Expect(Slot(test.key)).To(Equal(test.slot), "for %s", test.key)
- }
- })
-
- It("should extract keys from tags", func() {
- tests := []struct {
- one, two string
- }{
- {"foo{bar}", "bar"},
- {"{foo}bar", "foo"},
- {"{user1000}.following", "{user1000}.followers"},
- {"foo{{bar}}zap", "{bar"},
- {"foo{bar}{zap}", "bar"},
- }
-
- for _, test := range tests {
- Expect(Slot(test.one)).To(Equal(Slot(test.two)), "for %s <-> %s", test.one, test.two)
- }
- })
-
-})
diff --git a/vendor/github.com/go-redis/redis/internal/internal_test.go b/vendor/github.com/go-redis/redis/internal/internal_test.go
deleted file mode 100644
index 56ff611e1..000000000
--- a/vendor/github.com/go-redis/redis/internal/internal_test.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package internal
-
-import (
- "testing"
- "time"
-
- . "github.com/onsi/gomega"
-)
-
-func TestRetryBackoff(t *testing.T) {
- RegisterTestingT(t)
-
- for i := -1; i <= 16; i++ {
- backoff := RetryBackoff(i, time.Millisecond, 512*time.Millisecond)
- Expect(backoff >= 0).To(BeTrue())
- Expect(backoff <= 512*time.Millisecond).To(BeTrue())
- }
-}
diff --git a/vendor/github.com/go-redis/redis/internal/pool/bench_test.go b/vendor/github.com/go-redis/redis/internal/pool/bench_test.go
deleted file mode 100644
index e0bb52446..000000000
--- a/vendor/github.com/go-redis/redis/internal/pool/bench_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package pool_test
-
-import (
- "testing"
- "time"
-
- "github.com/go-redis/redis/internal/pool"
-)
-
-func benchmarkPoolGetPut(b *testing.B, poolSize int) {
- connPool := pool.NewConnPool(&pool.Options{
- Dialer: dummyDialer,
- PoolSize: poolSize,
- PoolTimeout: time.Second,
- IdleTimeout: time.Hour,
- IdleCheckFrequency: time.Hour,
- })
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- cn, _, err := connPool.Get()
- if err != nil {
- b.Fatal(err)
- }
- if err = connPool.Put(cn); err != nil {
- b.Fatal(err)
- }
- }
- })
-}
-
-func BenchmarkPoolGetPut10Conns(b *testing.B) {
- benchmarkPoolGetPut(b, 10)
-}
-
-func BenchmarkPoolGetPut100Conns(b *testing.B) {
- benchmarkPoolGetPut(b, 100)
-}
-
-func BenchmarkPoolGetPut1000Conns(b *testing.B) {
- benchmarkPoolGetPut(b, 1000)
-}
-
-func benchmarkPoolGetRemove(b *testing.B, poolSize int) {
- connPool := pool.NewConnPool(&pool.Options{
- Dialer: dummyDialer,
- PoolSize: poolSize,
- PoolTimeout: time.Second,
- IdleTimeout: time.Hour,
- IdleCheckFrequency: time.Hour,
- })
-
- b.ResetTimer()
-
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- cn, _, err := connPool.Get()
- if err != nil {
- b.Fatal(err)
- }
- if err := connPool.Remove(cn); err != nil {
- b.Fatal(err)
- }
- }
- })
-}
-
-func BenchmarkPoolGetRemove10Conns(b *testing.B) {
- benchmarkPoolGetRemove(b, 10)
-}
-
-func BenchmarkPoolGetRemove100Conns(b *testing.B) {
- benchmarkPoolGetRemove(b, 100)
-}
-
-func BenchmarkPoolGetRemove1000Conns(b *testing.B) {
- benchmarkPoolGetRemove(b, 1000)
-}
diff --git a/vendor/github.com/go-redis/redis/internal/pool/main_test.go b/vendor/github.com/go-redis/redis/internal/pool/main_test.go
deleted file mode 100644
index 43afe3fa9..000000000
--- a/vendor/github.com/go-redis/redis/internal/pool/main_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package pool_test
-
-import (
- "net"
- "sync"
- "testing"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-func TestGinkgoSuite(t *testing.T) {
- RegisterFailHandler(Fail)
- RunSpecs(t, "pool")
-}
-
-func perform(n int, cbs ...func(int)) {
- var wg sync.WaitGroup
- for _, cb := range cbs {
- for i := 0; i < n; i++ {
- wg.Add(1)
- go func(cb func(int), i int) {
- defer GinkgoRecover()
- defer wg.Done()
-
- cb(i)
- }(cb, i)
- }
- }
- wg.Wait()
-}
-
-func dummyDialer() (net.Conn, error) {
- return &net.TCPConn{}, nil
-}
diff --git a/vendor/github.com/go-redis/redis/internal/pool/pool_test.go b/vendor/github.com/go-redis/redis/internal/pool/pool_test.go
deleted file mode 100644
index 68c9a1bef..000000000
--- a/vendor/github.com/go-redis/redis/internal/pool/pool_test.go
+++ /dev/null
@@ -1,241 +0,0 @@
-package pool_test
-
-import (
- "testing"
- "time"
-
- "github.com/go-redis/redis/internal/pool"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("ConnPool", func() {
- var connPool *pool.ConnPool
-
- BeforeEach(func() {
- connPool = pool.NewConnPool(&pool.Options{
- Dialer: dummyDialer,
- PoolSize: 10,
- PoolTimeout: time.Hour,
- IdleTimeout: time.Millisecond,
- IdleCheckFrequency: time.Millisecond,
- })
- })
-
- AfterEach(func() {
- connPool.Close()
- })
-
- It("should unblock client when conn is removed", func() {
- // Reserve one connection.
- cn, _, err := connPool.Get()
- Expect(err).NotTo(HaveOccurred())
-
- // Reserve all other connections.
- var cns []*pool.Conn
- for i := 0; i < 9; i++ {
- cn, _, err := connPool.Get()
- Expect(err).NotTo(HaveOccurred())
- cns = append(cns, cn)
- }
-
- started := make(chan bool, 1)
- done := make(chan bool, 1)
- go func() {
- defer GinkgoRecover()
-
- started <- true
- _, _, err := connPool.Get()
- Expect(err).NotTo(HaveOccurred())
- done <- true
-
- err = connPool.Put(cn)
- Expect(err).NotTo(HaveOccurred())
- }()
- <-started
-
- // Check that Get is blocked.
- select {
- case <-done:
- Fail("Get is not blocked")
- default:
- // ok
- }
-
- err = connPool.Remove(cn)
- Expect(err).NotTo(HaveOccurred())
-
- // Check that Ping is unblocked.
- select {
- case <-done:
- // ok
- case <-time.After(time.Second):
- Fail("Get is not unblocked")
- }
-
- for _, cn := range cns {
- err = connPool.Put(cn)
- Expect(err).NotTo(HaveOccurred())
- }
- })
-})
-
-var _ = Describe("conns reaper", func() {
- const idleTimeout = time.Minute
-
- var connPool *pool.ConnPool
- var conns, idleConns, closedConns []*pool.Conn
-
- BeforeEach(func() {
- conns = nil
- closedConns = nil
-
- connPool = pool.NewConnPool(&pool.Options{
- Dialer: dummyDialer,
- PoolSize: 10,
- PoolTimeout: time.Second,
- IdleTimeout: idleTimeout,
- IdleCheckFrequency: time.Hour,
-
- OnClose: func(cn *pool.Conn) error {
- closedConns = append(closedConns, cn)
- return nil
- },
- })
-
- // add stale connections
- idleConns = nil
- for i := 0; i < 3; i++ {
- cn, _, err := connPool.Get()
- Expect(err).NotTo(HaveOccurred())
- cn.SetUsedAt(time.Now().Add(-2 * idleTimeout))
- conns = append(conns, cn)
- idleConns = append(idleConns, cn)
- }
-
- // add fresh connections
- for i := 0; i < 3; i++ {
- cn, _, err := connPool.Get()
- Expect(err).NotTo(HaveOccurred())
- conns = append(conns, cn)
- }
-
- for _, cn := range conns {
- Expect(connPool.Put(cn)).NotTo(HaveOccurred())
- }
-
- Expect(connPool.Len()).To(Equal(6))
- Expect(connPool.FreeLen()).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.FreeLen()).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.FreeLen()).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(idleConns)))
- Expect(closedConns).To(ConsistOf(idleConns))
- })
-
- 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()
- Expect(err).NotTo(HaveOccurred())
- Expect(cn).NotTo(BeNil())
- freeCns = append(freeCns, cn)
- }
-
- Expect(connPool.Len()).To(Equal(3))
- Expect(connPool.FreeLen()).To(Equal(0))
-
- cn, _, err := connPool.Get()
- Expect(err).NotTo(HaveOccurred())
- Expect(cn).NotTo(BeNil())
- conns = append(conns, cn)
-
- Expect(connPool.Len()).To(Equal(4))
- Expect(connPool.FreeLen()).To(Equal(0))
-
- err = connPool.Remove(cn)
- Expect(err).NotTo(HaveOccurred())
-
- Expect(connPool.Len()).To(Equal(3))
- Expect(connPool.FreeLen()).To(Equal(0))
-
- for _, cn := range freeCns {
- err := connPool.Put(cn)
- Expect(err).NotTo(HaveOccurred())
- }
-
- Expect(connPool.Len()).To(Equal(3))
- Expect(connPool.FreeLen()).To(Equal(3))
- }
- })
-})
-
-var _ = Describe("race", func() {
- var connPool *pool.ConnPool
- var C, N int
-
- BeforeEach(func() {
- C, N = 10, 1000
- if testing.Short() {
- C = 4
- N = 100
- }
- })
-
- AfterEach(func() {
- connPool.Close()
- })
-
- 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,
- })
-
- perform(C, func(id int) {
- for i := 0; i < N; i++ {
- cn, _, err := connPool.Get()
- Expect(err).NotTo(HaveOccurred())
- if err == nil {
- Expect(connPool.Put(cn)).NotTo(HaveOccurred())
- }
- }
- }, func(id int) {
- for i := 0; i < N; i++ {
- cn, _, err := connPool.Get()
- Expect(err).NotTo(HaveOccurred())
- if err == nil {
- Expect(connPool.Remove(cn)).NotTo(HaveOccurred())
- }
- }
- })
- })
-})
diff --git a/vendor/github.com/go-redis/redis/internal/proto/proto_test.go b/vendor/github.com/go-redis/redis/internal/proto/proto_test.go
deleted file mode 100644
index c9a820eb1..000000000
--- a/vendor/github.com/go-redis/redis/internal/proto/proto_test.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package proto_test
-
-import (
- "testing"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-func TestGinkgoSuite(t *testing.T) {
- RegisterFailHandler(Fail)
- RunSpecs(t, "proto")
-}
diff --git a/vendor/github.com/go-redis/redis/internal/proto/reader.go b/vendor/github.com/go-redis/redis/internal/proto/reader.go
index e5ae8a03e..d5d695358 100644
--- a/vendor/github.com/go-redis/redis/internal/proto/reader.go
+++ b/vendor/github.com/go-redis/redis/internal/proto/reader.go
@@ -6,7 +6,7 @@ import (
"io"
"strconv"
- "github.com/go-redis/redis/internal"
+ "github.com/go-redis/redis/internal/util"
)
const bytesAllocLimit = 1024 * 1024 // 1mb
@@ -19,6 +19,16 @@ const (
ArrayReply = '*'
)
+//------------------------------------------------------------------------------
+
+const Nil = RedisError("redis: nil")
+
+type RedisError string
+
+func (e RedisError) Error() string { return string(e) }
+
+//------------------------------------------------------------------------------
+
type MultiBulkParse func(*Reader, int64) (interface{}, error)
type Reader struct {
@@ -66,7 +76,7 @@ func (r *Reader) ReadLine() ([]byte, error) {
return nil, fmt.Errorf("redis: reply is empty")
}
if isNilReply(line) {
- return nil, internal.Nil
+ return nil, Nil
}
return line, nil
}
@@ -83,7 +93,7 @@ func (r *Reader) ReadReply(m MultiBulkParse) (interface{}, error) {
case StatusReply:
return parseStatusValue(line), nil
case IntReply:
- return parseInt(line[1:], 10, 64)
+ return util.ParseInt(line[1:], 10, 64)
case StringReply:
return r.readTmpBytesValue(line)
case ArrayReply:
@@ -105,7 +115,7 @@ func (r *Reader) ReadIntReply() (int64, error) {
case ErrorReply:
return 0, ParseErrorReply(line)
case IntReply:
- return parseInt(line[1:], 10, 64)
+ return util.ParseInt(line[1:], 10, 64)
default:
return 0, fmt.Errorf("redis: can't parse int reply: %.100q", line)
}
@@ -151,7 +161,7 @@ func (r *Reader) ReadFloatReply() (float64, error) {
if err != nil {
return 0, err
}
- return parseFloat(b, 64)
+ return util.ParseFloat(b, 64)
}
func (r *Reader) ReadArrayReply(m MultiBulkParse) (interface{}, error) {
@@ -221,7 +231,7 @@ func (r *Reader) ReadScanReply() ([]string, uint64, error) {
func (r *Reader) readTmpBytesValue(line []byte) ([]byte, error) {
if isNilReply(line) {
- return nil, internal.Nil
+ return nil, Nil
}
replyLen, err := strconv.Atoi(string(line[1:]))
@@ -241,7 +251,7 @@ func (r *Reader) ReadInt() (int64, error) {
if err != nil {
return 0, err
}
- return parseInt(b, 10, 64)
+ return util.ParseInt(b, 10, 64)
}
func (r *Reader) ReadUint() (uint64, error) {
@@ -249,7 +259,7 @@ func (r *Reader) ReadUint() (uint64, error) {
if err != nil {
return 0, err
}
- return parseUint(b, 10, 64)
+ return util.ParseUint(b, 10, 64)
}
// --------------------------------------------------------------------
@@ -303,7 +313,7 @@ func isNilReply(b []byte) bool {
}
func ParseErrorReply(line []byte) error {
- return internal.RedisError(string(line[1:]))
+ return RedisError(string(line[1:]))
}
func parseStatusValue(line []byte) []byte {
@@ -312,23 +322,7 @@ func parseStatusValue(line []byte) []byte {
func parseArrayLen(line []byte) (int64, error) {
if isNilReply(line) {
- return 0, internal.Nil
+ return 0, Nil
}
- return parseInt(line[1:], 10, 64)
-}
-
-func atoi(b []byte) (int, error) {
- return strconv.Atoi(internal.BytesToString(b))
-}
-
-func parseInt(b []byte, base int, bitSize int) (int64, error) {
- return strconv.ParseInt(internal.BytesToString(b), base, bitSize)
-}
-
-func parseUint(b []byte, base int, bitSize int) (uint64, error) {
- return strconv.ParseUint(internal.BytesToString(b), base, bitSize)
-}
-
-func parseFloat(b []byte, bitSize int) (float64, error) {
- return strconv.ParseFloat(internal.BytesToString(b), bitSize)
+ return util.ParseInt(line[1:], 10, 64)
}
diff --git a/vendor/github.com/go-redis/redis/internal/proto/reader_test.go b/vendor/github.com/go-redis/redis/internal/proto/reader_test.go
deleted file mode 100644
index 8d2d71be9..000000000
--- a/vendor/github.com/go-redis/redis/internal/proto/reader_test.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package proto_test
-
-import (
- "bytes"
- "strings"
- "testing"
-
- "github.com/go-redis/redis/internal/proto"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("Reader", func() {
-
- It("should read n bytes", func() {
- data, err := proto.NewReader(strings.NewReader("ABCDEFGHIJKLMNO")).ReadN(10)
- Expect(err).NotTo(HaveOccurred())
- Expect(len(data)).To(Equal(10))
- Expect(string(data)).To(Equal("ABCDEFGHIJ"))
-
- data, err = proto.NewReader(strings.NewReader(strings.Repeat("x", 8192))).ReadN(6000)
- Expect(err).NotTo(HaveOccurred())
- Expect(len(data)).To(Equal(6000))
- })
-
- It("should read lines", func() {
- p := proto.NewReader(strings.NewReader("$5\r\nhello\r\n"))
-
- data, err := p.ReadLine()
- Expect(err).NotTo(HaveOccurred())
- Expect(string(data)).To(Equal("$5"))
-
- data, err = p.ReadLine()
- Expect(err).NotTo(HaveOccurred())
- Expect(string(data)).To(Equal("hello"))
- })
-
-})
-
-func BenchmarkReader_ParseReply_Status(b *testing.B) {
- benchmarkParseReply(b, "+OK\r\n", nil, false)
-}
-
-func BenchmarkReader_ParseReply_Int(b *testing.B) {
- benchmarkParseReply(b, ":1\r\n", nil, false)
-}
-
-func BenchmarkReader_ParseReply_Error(b *testing.B) {
- benchmarkParseReply(b, "-Error message\r\n", nil, true)
-}
-
-func BenchmarkReader_ParseReply_String(b *testing.B) {
- benchmarkParseReply(b, "$5\r\nhello\r\n", nil, 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)
-}
-
-func benchmarkParseReply(b *testing.B, reply string, m proto.MultiBulkParse, wanterr bool) {
- buf := new(bytes.Buffer)
- for i := 0; i < b.N; i++ {
- buf.WriteString(reply)
- }
- p := proto.NewReader(buf)
- b.ResetTimer()
-
- for i := 0; i < b.N; i++ {
- _, err := p.ReadReply(m)
- 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/vendor/github.com/go-redis/redis/internal/proto/scan.go b/vendor/github.com/go-redis/redis/internal/proto/scan.go
index 0329ffd99..3bdb33f9d 100644
--- a/vendor/github.com/go-redis/redis/internal/proto/scan.go
+++ b/vendor/github.com/go-redis/redis/internal/proto/scan.go
@@ -5,7 +5,7 @@ import (
"fmt"
"reflect"
- "github.com/go-redis/redis/internal"
+ "github.com/go-redis/redis/internal/util"
)
func Scan(b []byte, v interface{}) error {
@@ -13,80 +13,80 @@ func Scan(b []byte, v interface{}) error {
case nil:
return fmt.Errorf("redis: Scan(nil)")
case *string:
- *v = internal.BytesToString(b)
+ *v = util.BytesToString(b)
return nil
case *[]byte:
*v = b
return nil
case *int:
var err error
- *v, err = atoi(b)
+ *v, err = util.Atoi(b)
return err
case *int8:
- n, err := parseInt(b, 10, 8)
+ n, err := util.ParseInt(b, 10, 8)
if err != nil {
return err
}
*v = int8(n)
return nil
case *int16:
- n, err := parseInt(b, 10, 16)
+ n, err := util.ParseInt(b, 10, 16)
if err != nil {
return err
}
*v = int16(n)
return nil
case *int32:
- n, err := parseInt(b, 10, 32)
+ n, err := util.ParseInt(b, 10, 32)
if err != nil {
return err
}
*v = int32(n)
return nil
case *int64:
- n, err := parseInt(b, 10, 64)
+ n, err := util.ParseInt(b, 10, 64)
if err != nil {
return err
}
*v = n
return nil
case *uint:
- n, err := parseUint(b, 10, 64)
+ n, err := util.ParseUint(b, 10, 64)
if err != nil {
return err
}
*v = uint(n)
return nil
case *uint8:
- n, err := parseUint(b, 10, 8)
+ n, err := util.ParseUint(b, 10, 8)
if err != nil {
return err
}
*v = uint8(n)
return nil
case *uint16:
- n, err := parseUint(b, 10, 16)
+ n, err := util.ParseUint(b, 10, 16)
if err != nil {
return err
}
*v = uint16(n)
return nil
case *uint32:
- n, err := parseUint(b, 10, 32)
+ n, err := util.ParseUint(b, 10, 32)
if err != nil {
return err
}
*v = uint32(n)
return nil
case *uint64:
- n, err := parseUint(b, 10, 64)
+ n, err := util.ParseUint(b, 10, 64)
if err != nil {
return err
}
*v = n
return nil
case *float32:
- n, err := parseFloat(b, 32)
+ n, err := util.ParseFloat(b, 32)
if err != nil {
return err
}
@@ -94,7 +94,7 @@ func Scan(b []byte, v interface{}) error {
return err
case *float64:
var err error
- *v, err = parseFloat(b, 64)
+ *v, err = util.ParseFloat(b, 64)
return err
case *bool:
*v = len(b) == 1 && b[0] == '1'
@@ -120,7 +120,7 @@ func ScanSlice(data []string, slice interface{}) error {
return fmt.Errorf("redis: ScanSlice(non-slice %T)", slice)
}
- next := internal.MakeSliceNextElemFunc(v)
+ next := makeSliceNextElemFunc(v)
for i, s := range data {
elem := next()
if err := Scan([]byte(s), elem.Addr().Interface()); err != nil {
@@ -131,3 +131,36 @@ func ScanSlice(data []string, slice interface{}) error {
return nil
}
+
+func makeSliceNextElemFunc(v reflect.Value) func() reflect.Value {
+ elemType := v.Type().Elem()
+
+ if elemType.Kind() == reflect.Ptr {
+ elemType = elemType.Elem()
+ return func() reflect.Value {
+ if v.Len() < v.Cap() {
+ v.Set(v.Slice(0, v.Len()+1))
+ elem := v.Index(v.Len() - 1)
+ if elem.IsNil() {
+ elem.Set(reflect.New(elemType))
+ }
+ return elem.Elem()
+ }
+
+ elem := reflect.New(elemType)
+ v.Set(reflect.Append(v, elem))
+ return elem.Elem()
+ }
+ }
+
+ zero := reflect.Zero(elemType)
+ return func() reflect.Value {
+ if v.Len() < v.Cap() {
+ v.Set(v.Slice(0, v.Len()+1))
+ return v.Index(v.Len() - 1)
+ }
+
+ v.Set(reflect.Append(v, zero))
+ return v.Index(v.Len() - 1)
+ }
+}
diff --git a/vendor/github.com/go-redis/redis/internal/proto/scan_test.go b/vendor/github.com/go-redis/redis/internal/proto/scan_test.go
deleted file mode 100644
index fadcd0561..000000000
--- a/vendor/github.com/go-redis/redis/internal/proto/scan_test.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package proto
-
-import (
- "encoding/json"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-type testScanSliceStruct struct {
- ID int
- Name string
-}
-
-func (s *testScanSliceStruct) MarshalBinary() ([]byte, error) {
- return json.Marshal(s)
-}
-
-func (s *testScanSliceStruct) UnmarshalBinary(b []byte) error {
- return json.Unmarshal(b, s)
-}
-
-var _ = Describe("ScanSlice", func() {
- data := []string{
- `{"ID":-1,"Name":"Back Yu"}`,
- `{"ID":1,"Name":"szyhf"}`,
- }
-
- It("[]testScanSliceStruct", func() {
- var slice []testScanSliceStruct
- err := ScanSlice(data, &slice)
- Expect(err).NotTo(HaveOccurred())
- Expect(slice).To(Equal([]testScanSliceStruct{
- {-1, "Back Yu"},
- {1, "szyhf"},
- }))
- })
-
- It("var testContainer []*testScanSliceStruct", func() {
- var slice []*testScanSliceStruct
- err := ScanSlice(data, &slice)
- Expect(err).NotTo(HaveOccurred())
- Expect(slice).To(Equal([]*testScanSliceStruct{
- {-1, "Back Yu"},
- {1, "szyhf"},
- }))
- })
-})
diff --git a/vendor/github.com/go-redis/redis/internal/proto/write_buffer.go b/vendor/github.com/go-redis/redis/internal/proto/write_buffer.go
index 096b6d76a..cc4014fb4 100644
--- a/vendor/github.com/go-redis/redis/internal/proto/write_buffer.go
+++ b/vendor/github.com/go-redis/redis/internal/proto/write_buffer.go
@@ -71,17 +71,15 @@ func (w *WriteBuffer) append(val interface{}) error {
} else {
w.AppendString("0")
}
- default:
- if bm, ok := val.(encoding.BinaryMarshaler); ok {
- bb, err := bm.MarshalBinary()
- if err != nil {
- return err
- }
- w.AppendBytes(bb)
- } else {
- return fmt.Errorf(
- "redis: can't marshal %T (consider implementing encoding.BinaryMarshaler)", val)
+ case encoding.BinaryMarshaler:
+ b, err := v.MarshalBinary()
+ if err != nil {
+ return err
}
+ w.AppendBytes(b)
+ default:
+ return fmt.Errorf(
+ "redis: can't marshal %T (consider implementing encoding.BinaryMarshaler)", val)
}
return nil
}
diff --git a/vendor/github.com/go-redis/redis/internal/proto/write_buffer_test.go b/vendor/github.com/go-redis/redis/internal/proto/write_buffer_test.go
deleted file mode 100644
index 84799ff3b..000000000
--- a/vendor/github.com/go-redis/redis/internal/proto/write_buffer_test.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package proto_test
-
-import (
- "testing"
- "time"
-
- "github.com/go-redis/redis/internal/proto"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("WriteBuffer", func() {
- var buf *proto.WriteBuffer
-
- BeforeEach(func() {
- buf = proto.NewWriteBuffer()
- })
-
- It("should reset", func() {
- buf.AppendString("string")
- Expect(buf.Len()).To(Equal(12))
- buf.Reset()
- Expect(buf.Len()).To(Equal(0))
- })
-
- It("should append args", func() {
- err := buf.Append([]interface{}{
- "string",
- 12,
- 34.56,
- []byte{'b', 'y', 't', 'e', 's'},
- true,
- nil,
- })
- Expect(err).NotTo(HaveOccurred())
- Expect(buf.Bytes()).To(Equal([]byte("*6\r\n" +
- "$6\r\nstring\r\n" +
- "$2\r\n12\r\n" +
- "$5\r\n34.56\r\n" +
- "$5\r\nbytes\r\n" +
- "$1\r\n1\r\n" +
- "$0\r\n" +
- "\r\n")))
- })
-
- It("should append marshalable args", func() {
- err := buf.Append([]interface{}{time.Unix(1414141414, 0)})
- Expect(err).NotTo(HaveOccurred())
- Expect(buf.Len()).To(Equal(26))
- })
-
-})
-
-func BenchmarkWriteBuffer_Append(b *testing.B) {
- buf := proto.NewWriteBuffer()
- args := []interface{}{"hello", "world", "foo", "bar"}
-
- for i := 0; i < b.N; i++ {
- buf.Append(args)
- buf.Reset()
- }
-}
diff --git a/vendor/github.com/go-redis/redis/internal/singleflight/singleflight.go b/vendor/github.com/go-redis/redis/internal/singleflight/singleflight.go
new file mode 100644
index 000000000..3b1741724
--- /dev/null
+++ b/vendor/github.com/go-redis/redis/internal/singleflight/singleflight.go
@@ -0,0 +1,64 @@
+/*
+Copyright 2013 Google Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package singleflight provides a duplicate function call suppression
+// mechanism.
+package singleflight
+
+import "sync"
+
+// call is an in-flight or completed Do call
+type call struct {
+ wg sync.WaitGroup
+ val interface{}
+ err error
+}
+
+// Group represents a class of work and forms a namespace in which
+// units of work can be executed with duplicate suppression.
+type Group struct {
+ mu sync.Mutex // protects m
+ m map[string]*call // lazily initialized
+}
+
+// Do executes and returns the results of the given function, making
+// sure that only one execution is in-flight for a given key at a
+// time. If a duplicate comes in, the duplicate caller waits for the
+// original to complete and receives the same results.
+func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
+ g.mu.Lock()
+ if g.m == nil {
+ g.m = make(map[string]*call)
+ }
+ if c, ok := g.m[key]; ok {
+ g.mu.Unlock()
+ c.wg.Wait()
+ return c.val, c.err
+ }
+ c := new(call)
+ c.wg.Add(1)
+ g.m[key] = c
+ g.mu.Unlock()
+
+ c.val, c.err = fn()
+ c.wg.Done()
+
+ g.mu.Lock()
+ delete(g.m, key)
+ g.mu.Unlock()
+
+ return c.val, c.err
+}
diff --git a/vendor/github.com/go-redis/redis/internal/util.go b/vendor/github.com/go-redis/redis/internal/util.go
index 1ba9805fe..ffd2353e0 100644
--- a/vendor/github.com/go-redis/redis/internal/util.go
+++ b/vendor/github.com/go-redis/redis/internal/util.go
@@ -1,6 +1,6 @@
package internal
-import "reflect"
+import "github.com/go-redis/redis/internal/util"
func ToLower(s string) string {
if isLower(s) {
@@ -15,7 +15,7 @@ func ToLower(s string) string {
}
b[i] = c
}
- return BytesToString(b)
+ return util.BytesToString(b)
}
func isLower(s string) bool {
@@ -27,36 +27,3 @@ func isLower(s string) bool {
}
return true
}
-
-func MakeSliceNextElemFunc(v reflect.Value) func() reflect.Value {
- elemType := v.Type().Elem()
-
- if elemType.Kind() == reflect.Ptr {
- elemType = elemType.Elem()
- return func() reflect.Value {
- if v.Len() < v.Cap() {
- v.Set(v.Slice(0, v.Len()+1))
- elem := v.Index(v.Len() - 1)
- if elem.IsNil() {
- elem.Set(reflect.New(elemType))
- }
- return elem.Elem()
- }
-
- elem := reflect.New(elemType)
- v.Set(reflect.Append(v, elem))
- return elem.Elem()
- }
- }
-
- zero := reflect.Zero(elemType)
- return func() reflect.Value {
- if v.Len() < v.Cap() {
- v.Set(v.Slice(0, v.Len()+1))
- return v.Index(v.Len() - 1)
- }
-
- v.Set(reflect.Append(v, zero))
- return v.Index(v.Len() - 1)
- }
-}
diff --git a/vendor/github.com/go-redis/redis/internal/safe.go b/vendor/github.com/go-redis/redis/internal/util/safe.go
index dc5f4cc8a..cd8918330 100644
--- a/vendor/github.com/go-redis/redis/internal/safe.go
+++ b/vendor/github.com/go-redis/redis/internal/util/safe.go
@@ -1,6 +1,6 @@
// +build appengine
-package internal
+package util
func BytesToString(b []byte) string {
return string(b)
diff --git a/vendor/github.com/go-redis/redis/internal/util/strconv.go b/vendor/github.com/go-redis/redis/internal/util/strconv.go
new file mode 100644
index 000000000..db5033802
--- /dev/null
+++ b/vendor/github.com/go-redis/redis/internal/util/strconv.go
@@ -0,0 +1,19 @@
+package util
+
+import "strconv"
+
+func Atoi(b []byte) (int, error) {
+ return strconv.Atoi(BytesToString(b))
+}
+
+func ParseInt(b []byte, base int, bitSize int) (int64, error) {
+ return strconv.ParseInt(BytesToString(b), base, bitSize)
+}
+
+func ParseUint(b []byte, base int, bitSize int) (uint64, error) {
+ return strconv.ParseUint(BytesToString(b), base, bitSize)
+}
+
+func ParseFloat(b []byte, bitSize int) (float64, error) {
+ return strconv.ParseFloat(BytesToString(b), bitSize)
+}
diff --git a/vendor/github.com/go-redis/redis/internal/unsafe.go b/vendor/github.com/go-redis/redis/internal/util/unsafe.go
index 3ae48c14b..93a89c55c 100644
--- a/vendor/github.com/go-redis/redis/internal/unsafe.go
+++ b/vendor/github.com/go-redis/redis/internal/util/unsafe.go
@@ -1,6 +1,6 @@
// +build !appengine
-package internal
+package util
import (
"unsafe"
diff --git a/vendor/github.com/go-redis/redis/iterator_test.go b/vendor/github.com/go-redis/redis/iterator_test.go
deleted file mode 100644
index a2e623813..000000000
--- a/vendor/github.com/go-redis/redis/iterator_test.go
+++ /dev/null
@@ -1,136 +0,0 @@
-package redis_test
-
-import (
- "fmt"
-
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("ScanIterator", func() {
- var client *redis.Client
-
- var seed = func(n int) error {
- pipe := client.Pipeline()
- for i := 1; i <= n; i++ {
- pipe.Set(fmt.Sprintf("K%02d", i), "x", 0).Err()
- }
- _, err := pipe.Exec()
- return err
- }
-
- var extraSeed = func(n int, m int) error {
- pipe := client.Pipeline()
- for i := 1; i <= m; i++ {
- pipe.Set(fmt.Sprintf("A%02d", i), "x", 0).Err()
- }
- for i := 1; i <= n; i++ {
- pipe.Set(fmt.Sprintf("K%02d", i), "x", 0).Err()
- }
- _, err := pipe.Exec()
- return err
- }
-
- var hashKey = "K_HASHTEST"
- var hashSeed = func(n int) error {
- pipe := client.Pipeline()
- for i := 1; i <= n; i++ {
- pipe.HSet(hashKey, fmt.Sprintf("K%02d", i), "x").Err()
- }
- _, err := pipe.Exec()
- return err
- }
-
- BeforeEach(func() {
- client = redis.NewClient(redisOptions())
- Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("should scan across empty DBs", func() {
- iter := client.Scan(0, "", 10).Iterator()
- Expect(iter.Next()).To(BeFalse())
- Expect(iter.Err()).NotTo(HaveOccurred())
- })
-
- It("should scan across one page", func() {
- Expect(seed(7)).NotTo(HaveOccurred())
-
- var vals []string
- iter := client.Scan(0, "", 0).Iterator()
- for iter.Next() {
- vals = append(vals, iter.Val())
- }
- Expect(iter.Err()).NotTo(HaveOccurred())
- Expect(vals).To(ConsistOf([]string{"K01", "K02", "K03", "K04", "K05", "K06", "K07"}))
- })
-
- It("should scan across multiple pages", func() {
- Expect(seed(71)).NotTo(HaveOccurred())
-
- var vals []string
- iter := client.Scan(0, "", 10).Iterator()
- for iter.Next() {
- vals = append(vals, iter.Val())
- }
- Expect(iter.Err()).NotTo(HaveOccurred())
- Expect(vals).To(HaveLen(71))
- Expect(vals).To(ContainElement("K01"))
- Expect(vals).To(ContainElement("K71"))
- })
-
- It("should hscan across multiple pages", func() {
- Expect(hashSeed(71)).NotTo(HaveOccurred())
-
- var vals []string
- iter := client.HScan(hashKey, 0, "", 10).Iterator()
- for iter.Next() {
- vals = append(vals, iter.Val())
- }
- Expect(iter.Err()).NotTo(HaveOccurred())
- Expect(vals).To(HaveLen(71 * 2))
- Expect(vals).To(ContainElement("K01"))
- Expect(vals).To(ContainElement("K71"))
- })
-
- It("should scan to page borders", func() {
- Expect(seed(20)).NotTo(HaveOccurred())
-
- var vals []string
- iter := client.Scan(0, "", 10).Iterator()
- for iter.Next() {
- vals = append(vals, iter.Val())
- }
- Expect(iter.Err()).NotTo(HaveOccurred())
- Expect(vals).To(HaveLen(20))
- })
-
- It("should scan with match", func() {
- Expect(seed(33)).NotTo(HaveOccurred())
-
- var vals []string
- iter := client.Scan(0, "K*2*", 10).Iterator()
- for iter.Next() {
- vals = append(vals, iter.Val())
- }
- Expect(iter.Err()).NotTo(HaveOccurred())
- Expect(vals).To(HaveLen(13))
- })
-
- It("should scan with match across empty pages", func() {
- Expect(extraSeed(2, 10)).NotTo(HaveOccurred())
-
- var vals []string
- iter := client.Scan(0, "K*", 1).Iterator()
- for iter.Next() {
- vals = append(vals, iter.Val())
- }
- Expect(iter.Err()).NotTo(HaveOccurred())
- Expect(vals).To(HaveLen(2))
- })
-})
diff --git a/vendor/github.com/go-redis/redis/main_test.go b/vendor/github.com/go-redis/redis/main_test.go
deleted file mode 100644
index 7c5a6a969..000000000
--- a/vendor/github.com/go-redis/redis/main_test.go
+++ /dev/null
@@ -1,351 +0,0 @@
-package redis_test
-
-import (
- "errors"
- "fmt"
- "net"
- "os"
- "os/exec"
- "path/filepath"
- "sync"
- "sync/atomic"
- "testing"
- "time"
-
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-const (
- redisPort = "6380"
- redisAddr = ":" + redisPort
- redisSecondaryPort = "6381"
-)
-
-const (
- ringShard1Port = "6390"
- ringShard2Port = "6391"
-)
-
-const (
- sentinelName = "mymaster"
- sentinelMasterPort = "8123"
- sentinelSlave1Port = "8124"
- sentinelSlave2Port = "8125"
- sentinelPort = "8126"
-)
-
-var (
- redisMain *redisProcess
- ringShard1, ringShard2 *redisProcess
- sentinelMaster, sentinelSlave1, sentinelSlave2, sentinel *redisProcess
-)
-
-var cluster = &clusterScenario{
- ports: []string{"8220", "8221", "8222", "8223", "8224", "8225"},
- nodeIds: make([]string, 6),
- processes: make(map[string]*redisProcess, 6),
- clients: make(map[string]*redis.Client, 6),
-}
-
-var _ = BeforeSuite(func() {
- var err error
-
- redisMain, err = startRedis(redisPort)
- Expect(err).NotTo(HaveOccurred())
-
- ringShard1, err = startRedis(ringShard1Port)
- Expect(err).NotTo(HaveOccurred())
-
- ringShard2, err = startRedis(ringShard2Port)
- Expect(err).NotTo(HaveOccurred())
-
- sentinelMaster, err = startRedis(sentinelMasterPort)
- Expect(err).NotTo(HaveOccurred())
-
- sentinel, err = startSentinel(sentinelPort, sentinelName, sentinelMasterPort)
- Expect(err).NotTo(HaveOccurred())
-
- sentinelSlave1, err = startRedis(
- sentinelSlave1Port, "--slaveof", "127.0.0.1", sentinelMasterPort)
- Expect(err).NotTo(HaveOccurred())
-
- sentinelSlave2, err = startRedis(
- sentinelSlave2Port, "--slaveof", "127.0.0.1", sentinelMasterPort)
- Expect(err).NotTo(HaveOccurred())
-
- Expect(startCluster(cluster)).NotTo(HaveOccurred())
-})
-
-var _ = AfterSuite(func() {
- Expect(redisMain.Close()).NotTo(HaveOccurred())
-
- Expect(ringShard1.Close()).NotTo(HaveOccurred())
- Expect(ringShard2.Close()).NotTo(HaveOccurred())
-
- Expect(sentinel.Close()).NotTo(HaveOccurred())
- Expect(sentinelSlave1.Close()).NotTo(HaveOccurred())
- Expect(sentinelSlave2.Close()).NotTo(HaveOccurred())
- Expect(sentinelMaster.Close()).NotTo(HaveOccurred())
-
- Expect(stopCluster(cluster)).NotTo(HaveOccurred())
-})
-
-func TestGinkgoSuite(t *testing.T) {
- RegisterFailHandler(Fail)
- RunSpecs(t, "go-redis")
-}
-
-//------------------------------------------------------------------------------
-
-func redisOptions() *redis.Options {
- return &redis.Options{
- Addr: redisAddr,
- DB: 15,
- DialTimeout: 10 * time.Second,
- ReadTimeout: 30 * time.Second,
- WriteTimeout: 30 * time.Second,
- PoolSize: 10,
- PoolTimeout: 30 * time.Second,
- IdleTimeout: 500 * time.Millisecond,
- IdleCheckFrequency: 500 * time.Millisecond,
- }
-}
-
-func redisClusterOptions() *redis.ClusterOptions {
- return &redis.ClusterOptions{
- DialTimeout: 10 * time.Second,
- ReadTimeout: 30 * time.Second,
- WriteTimeout: 30 * time.Second,
- PoolSize: 10,
- PoolTimeout: 30 * time.Second,
- IdleTimeout: 500 * time.Millisecond,
- IdleCheckFrequency: 500 * time.Millisecond,
- }
-}
-
-func redisRingOptions() *redis.RingOptions {
- return &redis.RingOptions{
- Addrs: map[string]string{
- "ringShardOne": ":" + ringShard1Port,
- "ringShardTwo": ":" + ringShard2Port,
- },
- DialTimeout: 10 * time.Second,
- ReadTimeout: 30 * time.Second,
- WriteTimeout: 30 * time.Second,
- PoolSize: 10,
- PoolTimeout: 30 * time.Second,
- IdleTimeout: 500 * time.Millisecond,
- IdleCheckFrequency: 500 * time.Millisecond,
- }
-}
-
-func perform(n int, cbs ...func(int)) {
- var wg sync.WaitGroup
- for _, cb := range cbs {
- for i := 0; i < n; i++ {
- wg.Add(1)
- go func(cb func(int), i int) {
- defer GinkgoRecover()
- defer wg.Done()
-
- cb(i)
- }(cb, i)
- }
- }
- wg.Wait()
-}
-
-func eventually(fn func() error, timeout time.Duration) error {
- var exit int32
- errCh := make(chan error)
- done := make(chan struct{})
-
- go func() {
- defer GinkgoRecover()
-
- for atomic.LoadInt32(&exit) == 0 {
- err := fn()
- if err == nil {
- close(done)
- return
- }
- select {
- case errCh <- err:
- default:
- }
- time.Sleep(timeout / 100)
- }
- }()
-
- select {
- case <-done:
- return nil
- case <-time.After(timeout):
- atomic.StoreInt32(&exit, 1)
- select {
- case err := <-errCh:
- return err
- default:
- return fmt.Errorf("timeout after %s", timeout)
- }
- }
-}
-
-func execCmd(name string, args ...string) (*os.Process, error) {
- cmd := exec.Command(name, args...)
- if testing.Verbose() {
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- }
- return cmd.Process, cmd.Start()
-}
-
-func connectTo(port string) (*redis.Client, error) {
- client := redis.NewClient(&redis.Options{
- Addr: ":" + port,
- })
-
- err := eventually(func() error {
- return client.Ping().Err()
- }, 30*time.Second)
- if err != nil {
- return nil, err
- }
-
- return client, nil
-}
-
-type redisProcess struct {
- *os.Process
- *redis.Client
-}
-
-func (p *redisProcess) Close() error {
- if err := p.Kill(); err != nil {
- return err
- }
-
- err := eventually(func() error {
- if err := p.Client.Ping().Err(); err != nil {
- return nil
- }
- return errors.New("client is not shutdown")
- }, 10*time.Second)
- if err != nil {
- return err
- }
-
- p.Client.Close()
- return nil
-}
-
-var (
- redisServerBin, _ = filepath.Abs(filepath.Join("testdata", "redis", "src", "redis-server"))
- redisServerConf, _ = filepath.Abs(filepath.Join("testdata", "redis.conf"))
-)
-
-func redisDir(port string) (string, error) {
- dir, err := filepath.Abs(filepath.Join("testdata", "instances", port))
- if err != nil {
- return "", err
- }
- if err := os.RemoveAll(dir); err != nil {
- return "", err
- }
- if err := os.MkdirAll(dir, 0775); err != nil {
- return "", err
- }
- return dir, nil
-}
-
-func startRedis(port string, args ...string) (*redisProcess, error) {
- dir, err := redisDir(port)
- if err != nil {
- return nil, err
- }
- if err = exec.Command("cp", "-f", redisServerConf, dir).Run(); err != nil {
- return nil, err
- }
-
- baseArgs := []string{filepath.Join(dir, "redis.conf"), "--port", port, "--dir", dir}
- process, err := execCmd(redisServerBin, append(baseArgs, args...)...)
- if err != nil {
- return nil, err
- }
-
- client, err := connectTo(port)
- if err != nil {
- process.Kill()
- return nil, err
- }
- return &redisProcess{process, client}, err
-}
-
-func startSentinel(port, masterName, masterPort string) (*redisProcess, error) {
- dir, err := redisDir(port)
- if err != nil {
- return nil, err
- }
- process, err := execCmd(redisServerBin, os.DevNull, "--sentinel", "--port", port, "--dir", dir)
- if err != nil {
- return nil, err
- }
- client, err := connectTo(port)
- if err != nil {
- process.Kill()
- return nil, err
- }
- for _, cmd := range []*redis.StatusCmd{
- redis.NewStatusCmd("SENTINEL", "MONITOR", masterName, "127.0.0.1", masterPort, "1"),
- redis.NewStatusCmd("SENTINEL", "SET", masterName, "down-after-milliseconds", "500"),
- redis.NewStatusCmd("SENTINEL", "SET", masterName, "failover-timeout", "1000"),
- redis.NewStatusCmd("SENTINEL", "SET", masterName, "parallel-syncs", "1"),
- } {
- client.Process(cmd)
- if err := cmd.Err(); err != nil {
- process.Kill()
- return nil, err
- }
- }
- return &redisProcess{process, client}, nil
-}
-
-//------------------------------------------------------------------------------
-
-type badConnError string
-
-func (e badConnError) Error() string { return string(e) }
-func (e badConnError) Timeout() bool { return false }
-func (e badConnError) Temporary() bool { return false }
-
-type badConn struct {
- net.TCPConn
-
- readDelay, writeDelay time.Duration
- readErr, writeErr error
-}
-
-var _ net.Conn = &badConn{}
-
-func (cn *badConn) Read([]byte) (int, error) {
- if cn.readDelay != 0 {
- time.Sleep(cn.readDelay)
- }
- if cn.readErr != nil {
- return 0, cn.readErr
- }
- return 0, badConnError("bad connection")
-}
-
-func (cn *badConn) Write([]byte) (int, error) {
- if cn.writeDelay != 0 {
- time.Sleep(cn.writeDelay)
- }
- if cn.writeErr != nil {
- return 0, cn.writeErr
- }
- return 0, badConnError("bad connection")
-}
diff --git a/vendor/github.com/go-redis/redis/options_test.go b/vendor/github.com/go-redis/redis/options_test.go
deleted file mode 100644
index 211f6b195..000000000
--- a/vendor/github.com/go-redis/redis/options_test.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// +build go1.7
-
-package redis
-
-import (
- "errors"
- "testing"
-)
-
-func TestParseURL(t *testing.T) {
- cases := []struct {
- u string
- addr string
- db int
- tls bool
- 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://localhost/?abc=123",
- "",
- 0, false, errors.New("no options supported"),
- },
- {
- "http://google.com",
- "",
- 0, false, errors.New("invalid redis URL scheme: http"),
- },
- {
- "redis://localhost/1/2/3/4",
- "",
- 0, false, errors.New("invalid redis URL path: /1/2/3/4"),
- },
- {
- "12345",
- "",
- 0, false, errors.New("invalid redis URL scheme: "),
- },
- {
- "redis://localhost/iamadatabase",
- "",
- 0, false, errors.New(`invalid redis 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 {
- 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)
- }
- 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")
- }
- })
- }
-}
diff --git a/vendor/github.com/go-redis/redis/parser.go b/vendor/github.com/go-redis/redis/parser.go
index b378abc4e..f0dc67f0e 100644
--- a/vendor/github.com/go-redis/redis/parser.go
+++ b/vendor/github.com/go-redis/redis/parser.go
@@ -14,17 +14,23 @@ func sliceParser(rd *proto.Reader, n int64) (interface{}, error) {
vals := make([]interface{}, 0, n)
for i := int64(0); i < n; i++ {
v, err := rd.ReadReply(sliceParser)
- if err == Nil {
- vals = append(vals, nil)
- } else if err != nil {
- return nil, err
- } else {
- switch vv := v.(type) {
- case []byte:
- vals = append(vals, string(vv))
- default:
- vals = append(vals, v)
+ if err != nil {
+ if err == Nil {
+ vals = append(vals, nil)
+ continue
+ }
+ if err, ok := err.(proto.RedisError); ok {
+ vals = append(vals, err)
+ continue
}
+ return nil, err
+ }
+
+ switch v := v.(type) {
+ case []byte:
+ vals = append(vals, string(v))
+ default:
+ vals = append(vals, v)
}
}
return vals, nil
diff --git a/vendor/github.com/go-redis/redis/pipeline_test.go b/vendor/github.com/go-redis/redis/pipeline_test.go
deleted file mode 100644
index 11896c6bb..000000000
--- a/vendor/github.com/go-redis/redis/pipeline_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package redis_test
-
-import (
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("pipelining", func() {
- var client *redis.Client
- var pipe *redis.Pipeline
-
- BeforeEach(func() {
- client = redis.NewClient(redisOptions())
- Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("supports block style", func() {
- var get *redis.StringCmd
- cmds, err := client.Pipelined(func(pipe redis.Pipeliner) error {
- get = pipe.Get("foo")
- return nil
- })
- Expect(err).To(Equal(redis.Nil))
- Expect(cmds).To(HaveLen(1))
- Expect(cmds[0]).To(Equal(get))
- Expect(get.Err()).To(Equal(redis.Nil))
- Expect(get.Val()).To(Equal(""))
- })
-
- assertPipeline := func() {
- It("returns no errors when there are no commands", func() {
- _, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- })
-
- It("discards queued commands", func() {
- pipe.Get("key")
- pipe.Discard()
- cmds, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(BeNil())
- })
-
- It("handles val/err", func() {
- err := client.Set("key", "value", 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- get := pipe.Get("key")
- cmds, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(1))
-
- val, err := get.Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("value"))
- })
- }
-
- Describe("Pipeline", func() {
- BeforeEach(func() {
- pipe = client.Pipeline().(*redis.Pipeline)
- })
-
- assertPipeline()
- })
-
- Describe("TxPipeline", func() {
- BeforeEach(func() {
- pipe = client.TxPipeline().(*redis.Pipeline)
- })
-
- assertPipeline()
- })
-})
diff --git a/vendor/github.com/go-redis/redis/pool_test.go b/vendor/github.com/go-redis/redis/pool_test.go
deleted file mode 100644
index 0ca09adc7..000000000
--- a/vendor/github.com/go-redis/redis/pool_test.go
+++ /dev/null
@@ -1,143 +0,0 @@
-package redis_test
-
-import (
- "time"
-
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("pool", func() {
- var client *redis.Client
-
- BeforeEach(func() {
- client = redis.NewClient(redisOptions())
- Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("respects max size", func() {
- perform(1000, func(id int) {
- val, err := client.Ping().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("PONG"))
- })
-
- pool := client.Pool()
- Expect(pool.Len()).To(BeNumerically("<=", 10))
- Expect(pool.FreeLen()).To(BeNumerically("<=", 10))
- Expect(pool.Len()).To(Equal(pool.FreeLen()))
- })
-
- It("respects max size on multi", func() {
- perform(1000, func(id int) {
- var ping *redis.StatusCmd
-
- err := client.Watch(func(tx *redis.Tx) error {
- cmds, err := tx.Pipelined(func(pipe redis.Pipeliner) error {
- ping = pipe.Ping()
- return nil
- })
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(1))
- return err
- })
- Expect(err).NotTo(HaveOccurred())
-
- Expect(ping.Err()).NotTo(HaveOccurred())
- Expect(ping.Val()).To(Equal("PONG"))
- })
-
- pool := client.Pool()
- Expect(pool.Len()).To(BeNumerically("<=", 10))
- Expect(pool.FreeLen()).To(BeNumerically("<=", 10))
- Expect(pool.Len()).To(Equal(pool.FreeLen()))
- })
-
- It("respects max size on pipelines", func() {
- perform(1000, func(id int) {
- pipe := client.Pipeline()
- ping := pipe.Ping()
- cmds, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(1))
- Expect(ping.Err()).NotTo(HaveOccurred())
- Expect(ping.Val()).To(Equal("PONG"))
- Expect(pipe.Close()).NotTo(HaveOccurred())
- })
-
- pool := client.Pool()
- Expect(pool.Len()).To(BeNumerically("<=", 10))
- Expect(pool.FreeLen()).To(BeNumerically("<=", 10))
- Expect(pool.Len()).To(Equal(pool.FreeLen()))
- })
-
- It("removes broken connections", func() {
- cn, _, err := client.Pool().Get()
- Expect(err).NotTo(HaveOccurred())
- cn.SetNetConn(&badConn{})
- Expect(client.Pool().Put(cn)).NotTo(HaveOccurred())
-
- err = client.Ping().Err()
- Expect(err).To(MatchError("bad connection"))
-
- val, err := client.Ping().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("PONG"))
-
- pool := client.Pool()
- Expect(pool.Len()).To(Equal(1))
- Expect(pool.FreeLen()).To(Equal(1))
-
- stats := pool.Stats()
- Expect(stats.Hits).To(Equal(uint32(2)))
- Expect(stats.Misses).To(Equal(uint32(2)))
- Expect(stats.Timeouts).To(Equal(uint32(0)))
- })
-
- It("reuses connections", func() {
- for i := 0; i < 100; i++ {
- val, err := client.Ping().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("PONG"))
- }
-
- pool := client.Pool()
- Expect(pool.Len()).To(Equal(1))
- Expect(pool.FreeLen()).To(Equal(1))
-
- stats := pool.Stats()
- Expect(stats.Hits).To(Equal(uint32(100)))
- Expect(stats.Misses).To(Equal(uint32(1)))
- Expect(stats.Timeouts).To(Equal(uint32(0)))
- })
-
- It("removes idle connections", func() {
- stats := client.PoolStats()
- Expect(stats).To(Equal(&redis.PoolStats{
- Hits: 0,
- Misses: 1,
- Timeouts: 0,
- TotalConns: 1,
- FreeConns: 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,
- FreeConns: 0,
- StaleConns: 1,
- }))
- })
-})
diff --git a/vendor/github.com/go-redis/redis/pubsub.go b/vendor/github.com/go-redis/redis/pubsub.go
index 3ee4ea9d0..b56728f3e 100644
--- a/vendor/github.com/go-redis/redis/pubsub.go
+++ b/vendor/github.com/go-redis/redis/pubsub.go
@@ -24,8 +24,8 @@ type PubSub struct {
mu sync.Mutex
cn *pool.Conn
- channels []string
- patterns []string
+ channels map[string]struct{}
+ patterns map[string]struct{}
closed bool
cmd *Cmd
@@ -67,12 +67,24 @@ func (c *PubSub) _conn(channels []string) (*pool.Conn, error) {
func (c *PubSub) resubscribe(cn *pool.Conn) error {
var firstErr error
if len(c.channels) > 0 {
- if err := c._subscribe(cn, "subscribe", c.channels...); err != nil && firstErr == nil {
+ channels := make([]string, len(c.channels))
+ i := 0
+ for channel := range c.channels {
+ channels[i] = channel
+ i++
+ }
+ if err := c._subscribe(cn, "subscribe", channels...); err != nil && firstErr == nil {
firstErr = err
}
}
if len(c.patterns) > 0 {
- if err := c._subscribe(cn, "psubscribe", c.patterns...); err != nil && firstErr == nil {
+ patterns := make([]string, len(c.patterns))
+ i := 0
+ for pattern := range c.patterns {
+ patterns[i] = pattern
+ i++
+ }
+ if err := c._subscribe(cn, "psubscribe", patterns...); err != nil && firstErr == nil {
firstErr = err
}
}
@@ -132,7 +144,12 @@ func (c *PubSub) Close() error {
func (c *PubSub) Subscribe(channels ...string) error {
c.mu.Lock()
err := c.subscribe("subscribe", channels...)
- c.channels = appendIfNotExists(c.channels, channels...)
+ if c.channels == nil {
+ c.channels = make(map[string]struct{})
+ }
+ for _, channel := range channels {
+ c.channels[channel] = struct{}{}
+ }
c.mu.Unlock()
return err
}
@@ -142,7 +159,12 @@ func (c *PubSub) Subscribe(channels ...string) error {
func (c *PubSub) PSubscribe(patterns ...string) error {
c.mu.Lock()
err := c.subscribe("psubscribe", patterns...)
- c.patterns = appendIfNotExists(c.patterns, patterns...)
+ if c.patterns == nil {
+ c.patterns = make(map[string]struct{})
+ }
+ for _, pattern := range patterns {
+ c.patterns[pattern] = struct{}{}
+ }
c.mu.Unlock()
return err
}
@@ -152,7 +174,9 @@ func (c *PubSub) PSubscribe(patterns ...string) error {
func (c *PubSub) Unsubscribe(channels ...string) error {
c.mu.Lock()
err := c.subscribe("unsubscribe", channels...)
- c.channels = remove(c.channels, channels...)
+ for _, channel := range channels {
+ delete(c.channels, channel)
+ }
c.mu.Unlock()
return err
}
@@ -162,7 +186,9 @@ func (c *PubSub) Unsubscribe(channels ...string) error {
func (c *PubSub) PUnsubscribe(patterns ...string) error {
c.mu.Lock()
err := c.subscribe("punsubscribe", patterns...)
- c.patterns = remove(c.patterns, patterns...)
+ for _, pattern := range patterns {
+ delete(c.patterns, pattern)
+ }
c.mu.Unlock()
return err
}
@@ -371,31 +397,3 @@ func (c *PubSub) Channel() <-chan *Message {
})
return c.ch
}
-
-func appendIfNotExists(ss []string, es ...string) []string {
-loop:
- for _, e := range es {
- for _, s := range ss {
- if s == e {
- continue loop
- }
- }
- ss = append(ss, e)
- }
- return ss
-}
-
-func remove(ss []string, es ...string) []string {
- if len(es) == 0 {
- return ss[:0]
- }
- for _, e := range es {
- for i, s := range ss {
- if s == e {
- ss = append(ss[:i], ss[i+1:]...)
- break
- }
- }
- }
- return ss
-}
diff --git a/vendor/github.com/go-redis/redis/pubsub_test.go b/vendor/github.com/go-redis/redis/pubsub_test.go
deleted file mode 100644
index 6a85bd038..000000000
--- a/vendor/github.com/go-redis/redis/pubsub_test.go
+++ /dev/null
@@ -1,443 +0,0 @@
-package redis_test
-
-import (
- "io"
- "net"
- "sync"
- "time"
-
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("PubSub", func() {
- var client *redis.Client
-
- BeforeEach(func() {
- client = redis.NewClient(redisOptions())
- Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("should support pattern matching", func() {
- pubsub := client.PSubscribe("mychannel*")
- defer pubsub.Close()
-
- {
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- subscr := msgi.(*redis.Subscription)
- Expect(subscr.Kind).To(Equal("psubscribe"))
- Expect(subscr.Channel).To(Equal("mychannel*"))
- Expect(subscr.Count).To(Equal(1))
- }
-
- {
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err.(net.Error).Timeout()).To(Equal(true))
- Expect(msgi).To(BeNil())
- }
-
- n, err := client.Publish("mychannel1", "hello").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(1)))
-
- Expect(pubsub.PUnsubscribe("mychannel*")).NotTo(HaveOccurred())
-
- {
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- subscr := msgi.(*redis.Message)
- Expect(subscr.Channel).To(Equal("mychannel1"))
- Expect(subscr.Pattern).To(Equal("mychannel*"))
- Expect(subscr.Payload).To(Equal("hello"))
- }
-
- {
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- subscr := msgi.(*redis.Subscription)
- Expect(subscr.Kind).To(Equal("punsubscribe"))
- Expect(subscr.Channel).To(Equal("mychannel*"))
- Expect(subscr.Count).To(Equal(0))
- }
-
- stats := client.PoolStats()
- Expect(stats.Misses).To(Equal(uint32(2)))
- })
-
- It("should pub/sub channels", func() {
- channels, err := client.PubSubChannels("mychannel*").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(channels).To(BeEmpty())
-
- pubsub := client.Subscribe("mychannel", "mychannel2")
- defer pubsub.Close()
-
- channels, err = client.PubSubChannels("mychannel*").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(channels).To(ConsistOf([]string{"mychannel", "mychannel2"}))
-
- channels, err = client.PubSubChannels("").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(channels).To(BeEmpty())
-
- channels, err = client.PubSubChannels("*").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(len(channels)).To(BeNumerically(">=", 2))
- })
-
- It("should return the numbers of subscribers", func() {
- pubsub := client.Subscribe("mychannel", "mychannel2")
- defer pubsub.Close()
-
- channels, err := client.PubSubNumSub("mychannel", "mychannel2", "mychannel3").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(channels).To(Equal(map[string]int64{
- "mychannel": 1,
- "mychannel2": 1,
- "mychannel3": 0,
- }))
- })
-
- It("should return the numbers of subscribers by pattern", func() {
- num, err := client.PubSubNumPat().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(num).To(Equal(int64(0)))
-
- pubsub := client.PSubscribe("*")
- defer pubsub.Close()
-
- num, err = client.PubSubNumPat().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(num).To(Equal(int64(1)))
- })
-
- It("should pub/sub", func() {
- pubsub := client.Subscribe("mychannel", "mychannel2")
- defer pubsub.Close()
-
- {
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- subscr := msgi.(*redis.Subscription)
- Expect(subscr.Kind).To(Equal("subscribe"))
- Expect(subscr.Channel).To(Equal("mychannel"))
- Expect(subscr.Count).To(Equal(1))
- }
-
- {
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- subscr := msgi.(*redis.Subscription)
- Expect(subscr.Kind).To(Equal("subscribe"))
- Expect(subscr.Channel).To(Equal("mychannel2"))
- Expect(subscr.Count).To(Equal(2))
- }
-
- {
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err.(net.Error).Timeout()).To(Equal(true))
- Expect(msgi).NotTo(HaveOccurred())
- }
-
- n, err := client.Publish("mychannel", "hello").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(1)))
-
- n, err = client.Publish("mychannel2", "hello2").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(1)))
-
- Expect(pubsub.Unsubscribe("mychannel", "mychannel2")).NotTo(HaveOccurred())
-
- {
- msgi, err := pubsub.ReceiveTimeout(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(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(time.Second)
- Expect(err).NotTo(HaveOccurred())
- subscr := msgi.(*redis.Subscription)
- Expect(subscr.Kind).To(Equal("unsubscribe"))
- Expect(subscr.Channel).To(Equal("mychannel"))
- Expect(subscr.Count).To(Equal(1))
- }
-
- {
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- subscr := msgi.(*redis.Subscription)
- Expect(subscr.Kind).To(Equal("unsubscribe"))
- Expect(subscr.Channel).To(Equal("mychannel2"))
- Expect(subscr.Count).To(Equal(0))
- }
-
- stats := client.PoolStats()
- Expect(stats.Misses).To(Equal(uint32(2)))
- })
-
- It("should ping/pong", func() {
- pubsub := client.Subscribe("mychannel")
- defer pubsub.Close()
-
- _, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
-
- err = pubsub.Ping("")
- Expect(err).NotTo(HaveOccurred())
-
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- pong := msgi.(*redis.Pong)
- Expect(pong.Payload).To(Equal(""))
- })
-
- It("should ping/pong with payload", func() {
- pubsub := client.Subscribe("mychannel")
- defer pubsub.Close()
-
- _, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
-
- err = pubsub.Ping("hello")
- Expect(err).NotTo(HaveOccurred())
-
- msgi, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- pong := msgi.(*redis.Pong)
- Expect(pong.Payload).To(Equal("hello"))
- })
-
- It("should multi-ReceiveMessage", func() {
- pubsub := client.Subscribe("mychannel")
- defer pubsub.Close()
-
- subscr, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- Expect(subscr).To(Equal(&redis.Subscription{
- Kind: "subscribe",
- Channel: "mychannel",
- Count: 1,
- }))
-
- err = client.Publish("mychannel", "hello").Err()
- Expect(err).NotTo(HaveOccurred())
-
- err = client.Publish("mychannel", "world").Err()
- Expect(err).NotTo(HaveOccurred())
-
- msg, err := pubsub.ReceiveMessage()
- Expect(err).NotTo(HaveOccurred())
- Expect(msg.Channel).To(Equal("mychannel"))
- Expect(msg.Payload).To(Equal("hello"))
-
- msg, err = pubsub.ReceiveMessage()
- Expect(err).NotTo(HaveOccurred())
- Expect(msg.Channel).To(Equal("mychannel"))
- Expect(msg.Payload).To(Equal("world"))
- })
-
- It("should ReceiveMessage after timeout", func() {
- timeout := 100 * time.Millisecond
-
- pubsub := client.Subscribe("mychannel")
- defer pubsub.Close()
-
- subscr, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- Expect(subscr).To(Equal(&redis.Subscription{
- Kind: "subscribe",
- Channel: "mychannel",
- Count: 1,
- }))
-
- done := make(chan bool, 1)
- go func() {
- defer GinkgoRecover()
- defer func() {
- done <- true
- }()
-
- time.Sleep(timeout + 100*time.Millisecond)
- n, err := client.Publish("mychannel", "hello").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(1)))
- }()
-
- msg, err := pubsub.ReceiveMessageTimeout(timeout)
- Expect(err).NotTo(HaveOccurred())
- Expect(msg.Channel).To(Equal("mychannel"))
- Expect(msg.Payload).To(Equal("hello"))
-
- Eventually(done).Should(Receive())
-
- stats := client.PoolStats()
- Expect(stats.Hits).To(Equal(uint32(1)))
- Expect(stats.Misses).To(Equal(uint32(1)))
- })
-
- It("returns an error when subscribe fails", func() {
- pubsub := client.Subscribe()
- defer pubsub.Close()
-
- pubsub.SetNetConn(&badConn{
- readErr: io.EOF,
- writeErr: io.EOF,
- })
-
- err := pubsub.Subscribe("mychannel")
- Expect(err).To(MatchError("EOF"))
-
- err = pubsub.Subscribe("mychannel")
- Expect(err).NotTo(HaveOccurred())
- })
-
- expectReceiveMessageOnError := func(pubsub *redis.PubSub) {
- pubsub.SetNetConn(&badConn{
- readErr: io.EOF,
- writeErr: io.EOF,
- })
-
- done := make(chan bool, 1)
- go func() {
- defer GinkgoRecover()
- defer func() {
- done <- true
- }()
-
- time.Sleep(100 * time.Millisecond)
- err := client.Publish("mychannel", "hello").Err()
- Expect(err).NotTo(HaveOccurred())
- }()
-
- msg, err := pubsub.ReceiveMessage()
- Expect(err).NotTo(HaveOccurred())
- Expect(msg.Channel).To(Equal("mychannel"))
- Expect(msg.Payload).To(Equal("hello"))
-
- Eventually(done).Should(Receive())
- }
-
- It("Subscribe should reconnect on ReceiveMessage error", func() {
- pubsub := client.Subscribe("mychannel")
- defer pubsub.Close()
-
- subscr, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- Expect(subscr).To(Equal(&redis.Subscription{
- Kind: "subscribe",
- Channel: "mychannel",
- Count: 1,
- }))
-
- expectReceiveMessageOnError(pubsub)
- })
-
- It("PSubscribe should reconnect on ReceiveMessage error", func() {
- pubsub := client.PSubscribe("mychannel")
- defer pubsub.Close()
-
- subscr, err := pubsub.ReceiveTimeout(time.Second)
- Expect(err).NotTo(HaveOccurred())
- Expect(subscr).To(Equal(&redis.Subscription{
- Kind: "psubscribe",
- Channel: "mychannel",
- Count: 1,
- }))
-
- expectReceiveMessageOnError(pubsub)
- })
-
- It("should return on Close", func() {
- pubsub := client.Subscribe("mychannel")
- defer pubsub.Close()
-
- var wg sync.WaitGroup
- wg.Add(1)
- go func() {
- defer GinkgoRecover()
-
- wg.Done()
- defer wg.Done()
-
- _, err := pubsub.ReceiveMessage()
- Expect(err).To(HaveOccurred())
- Expect(err).To(SatisfyAny(
- MatchError("redis: client is closed"),
- MatchError("use of closed network connection"), // Go 1.4
- ))
- }()
-
- wg.Wait()
- wg.Add(1)
-
- Expect(pubsub.Close()).NotTo(HaveOccurred())
-
- wg.Wait()
- })
-
- It("should ReceiveMessage without a subscription", func() {
- timeout := 100 * time.Millisecond
-
- pubsub := client.Subscribe()
- defer pubsub.Close()
-
- var wg sync.WaitGroup
- wg.Add(1)
- go func() {
- defer GinkgoRecover()
- defer wg.Done()
-
- time.Sleep(2 * timeout)
-
- err := pubsub.Subscribe("mychannel")
- Expect(err).NotTo(HaveOccurred())
-
- time.Sleep(timeout)
-
- err = client.Publish("mychannel", "hello").Err()
- Expect(err).NotTo(HaveOccurred())
- }()
-
- msg, err := pubsub.ReceiveMessageTimeout(timeout)
- Expect(err).NotTo(HaveOccurred())
- Expect(msg.Channel).To(Equal("mychannel"))
- Expect(msg.Payload).To(Equal("hello"))
-
- wg.Wait()
- })
-
- It("handles big message payload", func() {
- pubsub := client.Subscribe("mychannel")
- defer pubsub.Close()
-
- ch := pubsub.Channel()
-
- bigVal := bigVal()
- err := client.Publish("mychannel", bigVal).Err()
- Expect(err).NotTo(HaveOccurred())
-
- var msg *redis.Message
- Eventually(ch).Should(Receive(&msg))
- Expect(msg.Channel).To(Equal("mychannel"))
- Expect(msg.Payload).To(Equal(string(bigVal)))
- })
-})
diff --git a/vendor/github.com/go-redis/redis/race_test.go b/vendor/github.com/go-redis/redis/race_test.go
deleted file mode 100644
index 14264086c..000000000
--- a/vendor/github.com/go-redis/redis/race_test.go
+++ /dev/null
@@ -1,250 +0,0 @@
-package redis_test
-
-import (
- "bytes"
- "fmt"
- "net"
- "strconv"
- "testing"
- "time"
-
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("races", func() {
- var client *redis.Client
- var C, N int
-
- BeforeEach(func() {
- client = redis.NewClient(redisOptions())
- Expect(client.FlushDB().Err()).To(BeNil())
-
- C, N = 10, 1000
- if testing.Short() {
- C = 4
- N = 100
- }
- })
-
- AfterEach(func() {
- err := client.Close()
- Expect(err).NotTo(HaveOccurred())
- })
-
- It("should echo", func() {
- perform(C, func(id int) {
- for i := 0; i < N; i++ {
- msg := fmt.Sprintf("echo %d %d", id, i)
- echo, err := client.Echo(msg).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(echo).To(Equal(msg))
- }
- })
- })
-
- It("should incr", func() {
- key := "TestIncrFromGoroutines"
-
- perform(C, func(id int) {
- for i := 0; i < N; i++ {
- err := client.Incr(key).Err()
- Expect(err).NotTo(HaveOccurred())
- }
- })
-
- val, err := client.Get(key).Int64()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal(int64(C * N)))
- })
-
- It("should handle many keys", func() {
- perform(C, func(id int) {
- for i := 0; i < N; i++ {
- err := client.Set(
- fmt.Sprintf("keys.key-%d-%d", id, i),
- fmt.Sprintf("hello-%d-%d", id, i),
- 0,
- ).Err()
- Expect(err).NotTo(HaveOccurred())
- }
- })
-
- keys := client.Keys("keys.*")
- Expect(keys.Err()).NotTo(HaveOccurred())
- Expect(len(keys.Val())).To(Equal(C * N))
- })
-
- It("should handle many keys 2", func() {
- perform(C, func(id int) {
- keys := []string{"non-existent-key"}
- for i := 0; i < N; i++ {
- key := fmt.Sprintf("keys.key-%d", i)
- keys = append(keys, key)
-
- err := client.Set(key, fmt.Sprintf("hello-%d", i), 0).Err()
- Expect(err).NotTo(HaveOccurred())
- }
- keys = append(keys, "non-existent-key")
-
- vals, err := client.MGet(keys...).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(len(vals)).To(Equal(N + 2))
-
- for i := 0; i < N; i++ {
- Expect(vals[i+1]).To(Equal(fmt.Sprintf("hello-%d", i)))
- }
-
- Expect(vals[0]).To(BeNil())
- Expect(vals[N+1]).To(BeNil())
- })
- })
-
- It("should handle big vals in Get", func() {
- C, N = 4, 100
-
- bigVal := bigVal()
-
- err := client.Set("key", bigVal, 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- // Reconnect to get new connection.
- Expect(client.Close()).To(BeNil())
- client = redis.NewClient(redisOptions())
-
- perform(C, func(id int) {
- for i := 0; i < N; i++ {
- got, err := client.Get("key").Bytes()
- Expect(err).NotTo(HaveOccurred())
- Expect(got).To(Equal(bigVal))
- }
- })
- })
-
- It("should handle big vals in Set", func() {
- C, N = 4, 100
-
- bigVal := bigVal()
- perform(C, func(id int) {
- for i := 0; i < N; i++ {
- err := client.Set("key", bigVal, 0).Err()
- Expect(err).NotTo(HaveOccurred())
- }
- })
- })
-
- It("should select db", func() {
- err := client.Set("db", 1, 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- perform(C, func(id int) {
- opt := redisOptions()
- opt.DB = id
- client := redis.NewClient(opt)
- for i := 0; i < N; i++ {
- err := client.Set("db", id, 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- n, err := client.Get("db").Int64()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(id)))
- }
- err := client.Close()
- Expect(err).NotTo(HaveOccurred())
- })
-
- n, err := client.Get("db").Int64()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(1)))
- })
-
- It("should select DB with read timeout", func() {
- perform(C, func(id int) {
- opt := redisOptions()
- opt.DB = id
- opt.ReadTimeout = time.Nanosecond
- client := redis.NewClient(opt)
-
- perform(C, func(id int) {
- err := client.Ping().Err()
- Expect(err).To(HaveOccurred())
- Expect(err.(net.Error).Timeout()).To(BeTrue())
- })
-
- err := client.Close()
- Expect(err).NotTo(HaveOccurred())
- })
- })
-
- It("should Watch/Unwatch", func() {
- err := client.Set("key", "0", 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- perform(C, func(id int) {
- for i := 0; i < N; i++ {
- err := client.Watch(func(tx *redis.Tx) error {
- val, err := tx.Get("key").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).NotTo(Equal(redis.Nil))
-
- num, err := strconv.ParseInt(val, 10, 64)
- Expect(err).NotTo(HaveOccurred())
-
- cmds, err := tx.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Set("key", strconv.FormatInt(num+1, 10), 0)
- return nil
- })
- Expect(cmds).To(HaveLen(1))
- return err
- }, "key")
- if err == redis.TxFailedErr {
- i--
- continue
- }
- Expect(err).NotTo(HaveOccurred())
- }
- })
-
- val, err := client.Get("key").Int64()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal(int64(C * N)))
- })
-
- It("should Pipeline", func() {
- perform(C, func(id int) {
- pipe := client.Pipeline()
- for i := 0; i < N; i++ {
- pipe.Echo(fmt.Sprint(i))
- }
-
- cmds, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(N))
-
- for i := 0; i < N; i++ {
- Expect(cmds[i].(*redis.StringCmd).Val()).To(Equal(fmt.Sprint(i)))
- }
- })
- })
-
- It("should Pipeline", func() {
- pipe := client.Pipeline()
- perform(N, func(id int) {
- pipe.Incr("key")
- })
-
- cmds, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(N))
-
- n, err := client.Get("key").Int64()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(N)))
- })
-})
-
-func bigVal() []byte {
- return bytes.Repeat([]byte{'*'}, 1<<17) // 128kb
-}
diff --git a/vendor/github.com/go-redis/redis/redis.go b/vendor/github.com/go-redis/redis/redis.go
index cf402986d..7a606b70e 100644
--- a/vendor/github.com/go-redis/redis/redis.go
+++ b/vendor/github.com/go-redis/redis/redis.go
@@ -1,6 +1,7 @@
package redis
import (
+ "context"
"fmt"
"log"
"os"
@@ -11,8 +12,8 @@ import (
"github.com/go-redis/redis/internal/proto"
)
-// Nil reply redis returned when key does not exist.
-const Nil = internal.Nil
+// Nil reply Redis returns when key does not exist.
+const Nil = proto.Nil
func init() {
SetLogger(log.New(os.Stderr, "redis: ", log.LstdFlags|log.Lshortfile))
@@ -22,6 +23,17 @@ func SetLogger(logger *log.Logger) {
internal.Logger = logger
}
+type baseClient struct {
+ opt *Options
+ connPool pool.Pooler
+
+ process func(Cmder) error
+ processPipeline func([]Cmder) error
+ processTxPipeline func([]Cmder) error
+
+ onClose func() error // hook called when client is closed
+}
+
func (c *baseClient) init() {
c.process = c.defaultProcess
c.processPipeline = c.defaultProcessPipeline
@@ -84,16 +96,7 @@ func (c *baseClient) initConn(cn *pool.Conn) error {
return nil
}
- // Temp client to initialize connection.
- conn := &Conn{
- baseClient: baseClient{
- opt: c.opt,
- connPool: pool.NewSingleConnPool(cn),
- },
- }
- conn.baseClient.init()
- conn.statefulCmdable.setProcessor(conn.Process)
-
+ conn := newConn(c.opt, cn)
_, err := conn.Pipelined(func(pipe Pipeliner) error {
if c.opt.Password != "" {
pipe.Auth(c.opt.Password)
@@ -119,10 +122,7 @@ func (c *baseClient) initConn(cn *pool.Conn) error {
return nil
}
-// WrapProcess replaces the process func. It takes a function createWrapper
-// which is supplied by the user. createWrapper takes the old process func as
-// an input and returns the new wrapper process func. createWrapper should
-// use call the old process func within the new process func.
+// WrapProcess wraps function that processes Redis commands.
func (c *baseClient) WrapProcess(fn func(oldProcess func(cmd Cmder) error) func(cmd Cmder) error) {
c.process = fn(c.process)
}
@@ -338,33 +338,52 @@ func (c *baseClient) txPipelineReadQueued(cn *pool.Conn, cmds []Cmder) error {
type Client struct {
baseClient
cmdable
+
+ ctx context.Context
}
-func newClient(opt *Options, pool pool.Pooler) *Client {
+// NewClient returns a client to the Redis Server specified by Options.
+func NewClient(opt *Options) *Client {
+ opt.init()
+
c := Client{
baseClient: baseClient{
opt: opt,
- connPool: pool,
+ connPool: newConnPool(opt),
},
}
c.baseClient.init()
- c.cmdable.setProcessor(c.Process)
+ c.init()
+
return &c
}
-// NewClient returns a client to the Redis Server specified by Options.
-func NewClient(opt *Options) *Client {
- opt.init()
- return newClient(opt, newConnPool(opt))
+func (c *Client) init() {
+ c.cmdable.setProcessor(c.Process)
}
-func (c *Client) copy() *Client {
- c2 := new(Client)
- *c2 = *c
- c2.cmdable.setProcessor(c2.Process)
+func (c *Client) Context() context.Context {
+ if c.ctx != nil {
+ return c.ctx
+ }
+ return context.Background()
+}
+
+func (c *Client) WithContext(ctx context.Context) *Client {
+ if ctx == nil {
+ panic("nil context")
+ }
+ c2 := c.copy()
+ c2.ctx = ctx
return c2
}
+func (c *Client) copy() *Client {
+ cp := *c
+ cp.init()
+ return &cp
+}
+
// Options returns read-only Options that were used to create the client.
func (c *Client) Options() *Options {
return c.opt
@@ -442,6 +461,18 @@ type Conn struct {
statefulCmdable
}
+func newConn(opt *Options, cn *pool.Conn) *Conn {
+ c := Conn{
+ baseClient: baseClient{
+ opt: opt,
+ connPool: pool.NewSingleConnPool(cn),
+ },
+ }
+ c.baseClient.init()
+ c.statefulCmdable.setProcessor(c.Process)
+ return &c
+}
+
func (c *Conn) Pipelined(fn func(Pipeliner) error) ([]Cmder, error) {
return c.Pipeline().Pipelined(fn)
}
diff --git a/vendor/github.com/go-redis/redis/redis_context.go b/vendor/github.com/go-redis/redis/redis_context.go
deleted file mode 100644
index c00e505f6..000000000
--- a/vendor/github.com/go-redis/redis/redis_context.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// +build go1.7
-
-package redis
-
-import (
- "context"
-
- "github.com/go-redis/redis/internal/pool"
-)
-
-type baseClient struct {
- connPool pool.Pooler
- opt *Options
-
- process func(Cmder) error
- processPipeline func([]Cmder) error
- processTxPipeline func([]Cmder) error
-
- onClose func() error // hook called when client is closed
-
- ctx context.Context
-}
-
-func (c *Client) Context() context.Context {
- if c.ctx != nil {
- return c.ctx
- }
- return context.Background()
-}
-
-func (c *Client) WithContext(ctx context.Context) *Client {
- if ctx == nil {
- panic("nil context")
- }
- c2 := c.copy()
- c2.ctx = ctx
- return c2
-}
diff --git a/vendor/github.com/go-redis/redis/redis_no_context.go b/vendor/github.com/go-redis/redis/redis_no_context.go
deleted file mode 100644
index 8555c5c09..000000000
--- a/vendor/github.com/go-redis/redis/redis_no_context.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// +build !go1.7
-
-package redis
-
-import (
- "github.com/go-redis/redis/internal/pool"
-)
-
-type baseClient struct {
- connPool pool.Pooler
- opt *Options
-
- process func(Cmder) error
- processPipeline func([]Cmder) error
- processTxPipeline func([]Cmder) error
-
- onClose func() error // hook called when client is closed
-}
diff --git a/vendor/github.com/go-redis/redis/redis_test.go b/vendor/github.com/go-redis/redis/redis_test.go
deleted file mode 100644
index 49d3fb329..000000000
--- a/vendor/github.com/go-redis/redis/redis_test.go
+++ /dev/null
@@ -1,364 +0,0 @@
-package redis_test
-
-import (
- "bytes"
- "net"
- "time"
-
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("Client", func() {
- var client *redis.Client
-
- BeforeEach(func() {
- client = redis.NewClient(redisOptions())
- Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- client.Close()
- })
-
- It("should Stringer", func() {
- Expect(client.String()).To(Equal("Redis<:6380 db:15>"))
- })
-
- It("should ping", func() {
- val, err := client.Ping().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("PONG"))
- })
-
- It("should return pool stats", func() {
- Expect(client.PoolStats()).To(BeAssignableToTypeOf(&redis.PoolStats{}))
- })
-
- It("should support custom dialers", func() {
- custom := redis.NewClient(&redis.Options{
- Addr: ":1234",
- Dialer: func() (net.Conn, error) {
- return net.Dial("tcp", redisAddr)
- },
- })
-
- val, err := custom.Ping().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("PONG"))
- Expect(custom.Close()).NotTo(HaveOccurred())
- })
-
- It("should close", func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- err := client.Ping().Err()
- Expect(err).To(MatchError("redis: client is closed"))
- })
-
- It("should close pubsub without closing the client", func() {
- pubsub := client.Subscribe()
- Expect(pubsub.Close()).NotTo(HaveOccurred())
-
- _, err := pubsub.Receive()
- Expect(err).To(MatchError("redis: client is closed"))
- Expect(client.Ping().Err()).NotTo(HaveOccurred())
- })
-
- It("should close Tx without closing the client", func() {
- err := client.Watch(func(tx *redis.Tx) error {
- _, err := tx.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Ping()
- return nil
- })
- return err
- })
- Expect(err).NotTo(HaveOccurred())
-
- Expect(client.Ping().Err()).NotTo(HaveOccurred())
- })
-
- It("should close pipeline without closing the client", func() {
- pipeline := client.Pipeline()
- Expect(pipeline.Close()).NotTo(HaveOccurred())
-
- pipeline.Ping()
- _, err := pipeline.Exec()
- Expect(err).To(MatchError("redis: client is closed"))
-
- Expect(client.Ping().Err()).NotTo(HaveOccurred())
- })
-
- It("should close pubsub when client is closed", func() {
- pubsub := client.Subscribe()
- Expect(client.Close()).NotTo(HaveOccurred())
-
- _, err := pubsub.Receive()
- Expect(err).To(MatchError("redis: client is closed"))
-
- 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,
- DB: 2,
- })
- Expect(db2.FlushDB().Err()).NotTo(HaveOccurred())
- Expect(db2.Get("db").Err()).To(Equal(redis.Nil))
- Expect(db2.Set("db", 2, 0).Err()).NotTo(HaveOccurred())
-
- n, err := db2.Get("db").Int64()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(2)))
-
- Expect(client.Get("db").Err()).To(Equal(redis.Nil))
-
- Expect(db2.FlushDB().Err()).NotTo(HaveOccurred())
- Expect(db2.Close()).NotTo(HaveOccurred())
- })
-
- It("processes custom commands", func() {
- cmd := redis.NewCmd("PING")
- client.Process(cmd)
-
- // Flush buffers.
- Expect(client.Echo("hello").Err()).NotTo(HaveOccurred())
-
- Expect(cmd.Err()).NotTo(HaveOccurred())
- Expect(cmd.Val()).To(Equal("PONG"))
- })
-
- It("should retry command on network error", func() {
- Expect(client.Close()).NotTo(HaveOccurred())
-
- client = redis.NewClient(&redis.Options{
- Addr: redisAddr,
- MaxRetries: 1,
- })
-
- // Put bad connection in the pool.
- cn, _, err := client.Pool().Get()
- Expect(err).NotTo(HaveOccurred())
-
- cn.SetNetConn(&badConn{})
- err = client.Pool().Put(cn)
- Expect(err).NotTo(HaveOccurred())
-
- err = client.Ping().Err()
- Expect(err).NotTo(HaveOccurred())
- })
-
- It("should retry with backoff", func() {
- Expect(client.Close()).NotTo(HaveOccurred())
-
- // use up all the available connections to force a fail
- connectionHogClient := redis.NewClient(&redis.Options{
- Addr: redisAddr,
- MaxRetries: 1,
- })
- defer connectionHogClient.Close()
-
- for i := 0; i <= 1002; i++ {
- connectionHogClient.Pool().NewConn()
- }
-
- clientNoRetry := redis.NewClient(&redis.Options{
- Addr: redisAddr,
- PoolSize: 1,
- MaxRetryBackoff: -1,
- })
- defer clientNoRetry.Close()
-
- clientRetry := redis.NewClient(&redis.Options{
- Addr: redisAddr,
- MaxRetries: 5,
- PoolSize: 1,
- MaxRetryBackoff: 128 * time.Millisecond,
- })
- defer clientRetry.Close()
-
- startNoRetry := time.Now()
- err := clientNoRetry.Ping().Err()
- Expect(err).To(HaveOccurred())
- elapseNoRetry := time.Since(startNoRetry)
-
- startRetry := time.Now()
- err = clientRetry.Ping().Err()
- Expect(err).To(HaveOccurred())
- elapseRetry := time.Since(startRetry)
-
- Expect(elapseRetry > elapseNoRetry).To(BeTrue())
- })
-
- It("should update conn.UsedAt on read/write", func() {
- cn, _, err := client.Pool().Get()
- Expect(err).NotTo(HaveOccurred())
- Expect(cn.UsedAt).NotTo(BeZero())
- createdAt := cn.UsedAt()
-
- err = client.Pool().Put(cn)
- Expect(err).NotTo(HaveOccurred())
- Expect(cn.UsedAt().Equal(createdAt)).To(BeTrue())
-
- err = client.Ping().Err()
- Expect(err).NotTo(HaveOccurred())
-
- cn, _, err = client.Pool().Get()
- Expect(err).NotTo(HaveOccurred())
- Expect(cn).NotTo(BeNil())
- Expect(cn.UsedAt().After(createdAt)).To(BeTrue())
- })
-
- It("should process command with special chars", func() {
- set := client.Set("key", "hello1\r\nhello2\r\n", 0)
- Expect(set.Err()).NotTo(HaveOccurred())
- Expect(set.Val()).To(Equal("OK"))
-
- get := client.Get("key")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("hello1\r\nhello2\r\n"))
- })
-
- It("should handle big vals", func() {
- bigVal := bytes.Repeat([]byte{'*'}, 2e6)
-
- err := client.Set("key", bigVal, 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- // Reconnect to get new connection.
- Expect(client.Close()).NotTo(HaveOccurred())
- client = redis.NewClient(redisOptions())
-
- got, err := client.Get("key").Bytes()
- Expect(err).NotTo(HaveOccurred())
- Expect(got).To(Equal(bigVal))
- })
-
- It("should call WrapProcess", func() {
- var wrapperFnCalled bool
-
- client.WrapProcess(func(oldProcess func(redis.Cmder) error) func(redis.Cmder) error {
- return func(cmd redis.Cmder) error {
- wrapperFnCalled = true
- return oldProcess(cmd)
- }
- })
-
- Expect(client.Ping().Err()).NotTo(HaveOccurred())
-
- Expect(wrapperFnCalled).To(BeTrue())
- })
-})
-
-var _ = Describe("Client timeout", func() {
- var opt *redis.Options
- var client *redis.Client
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- testTimeout := func() {
- It("Ping timeouts", func() {
- err := client.Ping().Err()
- Expect(err).To(HaveOccurred())
- Expect(err.(net.Error).Timeout()).To(BeTrue())
- })
-
- It("Pipeline timeouts", func() {
- _, err := client.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Ping()
- return nil
- })
- Expect(err).To(HaveOccurred())
- Expect(err.(net.Error).Timeout()).To(BeTrue())
- })
-
- It("Subscribe timeouts", func() {
- if opt.WriteTimeout == 0 {
- return
- }
-
- pubsub := client.Subscribe()
- defer pubsub.Close()
-
- err := pubsub.Subscribe("_")
- Expect(err).To(HaveOccurred())
- Expect(err.(net.Error).Timeout()).To(BeTrue())
- })
-
- It("Tx timeouts", func() {
- err := client.Watch(func(tx *redis.Tx) error {
- return tx.Ping().Err()
- })
- Expect(err).To(HaveOccurred())
- Expect(err.(net.Error).Timeout()).To(BeTrue())
- })
-
- It("Tx Pipeline timeouts", func() {
- err := client.Watch(func(tx *redis.Tx) error {
- _, err := tx.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Ping()
- return nil
- })
- return err
- })
- Expect(err).To(HaveOccurred())
- Expect(err.(net.Error).Timeout()).To(BeTrue())
- })
- }
-
- Context("read timeout", func() {
- BeforeEach(func() {
- opt = redisOptions()
- opt.ReadTimeout = time.Nanosecond
- opt.WriteTimeout = -1
- client = redis.NewClient(opt)
- })
-
- testTimeout()
- })
-
- Context("write timeout", func() {
- BeforeEach(func() {
- opt = redisOptions()
- opt.ReadTimeout = -1
- opt.WriteTimeout = time.Nanosecond
- client = redis.NewClient(opt)
- })
-
- testTimeout()
- })
-})
-
-var _ = Describe("Client OnConnect", func() {
- var client *redis.Client
-
- BeforeEach(func() {
- opt := redisOptions()
- opt.DB = 0
- opt.OnConnect = func(cn *redis.Conn) error {
- return cn.ClientSetName("on_connect").Err()
- }
-
- client = redis.NewClient(opt)
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("calls OnConnect", func() {
- name, err := client.ClientGetName().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(name).To(Equal("on_connect"))
- })
-})
diff --git a/vendor/github.com/go-redis/redis/ring.go b/vendor/github.com/go-redis/redis/ring.go
index 10f33ed00..6d2877413 100644
--- a/vendor/github.com/go-redis/redis/ring.go
+++ b/vendor/github.com/go-redis/redis/ring.go
@@ -1,6 +1,7 @@
package redis
import (
+ "context"
"errors"
"fmt"
"math/rand"
@@ -15,6 +16,8 @@ import (
"github.com/go-redis/redis/internal/pool"
)
+const nreplicas = 100
+
var errRingShardsDown = errors.New("redis: all ring shards are down")
// RingOptions are used to configure a ring client and should be
@@ -85,6 +88,8 @@ func (opt *RingOptions) clientOptions() *Options {
}
}
+//------------------------------------------------------------------------------
+
type ringShard struct {
Client *Client
down int32
@@ -125,6 +130,150 @@ func (shard *ringShard) Vote(up bool) bool {
return shard.IsDown()
}
+//------------------------------------------------------------------------------
+
+type ringShards struct {
+ mu sync.RWMutex
+ hash *consistenthash.Map
+ shards map[string]*ringShard // read only
+ list []*ringShard // read only
+ closed bool
+}
+
+func newRingShards() *ringShards {
+ return &ringShards{
+ hash: consistenthash.New(nreplicas, nil),
+ shards: make(map[string]*ringShard),
+ }
+}
+
+func (c *ringShards) Add(name string, cl *Client) {
+ shard := &ringShard{Client: cl}
+ c.hash.Add(name)
+ c.shards[name] = shard
+ c.list = append(c.list, shard)
+}
+
+func (c *ringShards) List() []*ringShard {
+ c.mu.RLock()
+ list := c.list
+ c.mu.RUnlock()
+ return list
+}
+
+func (c *ringShards) Hash(key string) string {
+ c.mu.RLock()
+ hash := c.hash.Get(key)
+ c.mu.RUnlock()
+ return hash
+}
+
+func (c *ringShards) GetByKey(key string) (*ringShard, error) {
+ key = hashtag.Key(key)
+
+ c.mu.RLock()
+
+ if c.closed {
+ c.mu.RUnlock()
+ return nil, pool.ErrClosed
+ }
+
+ hash := c.hash.Get(key)
+ if hash == "" {
+ c.mu.RUnlock()
+ return nil, errRingShardsDown
+ }
+
+ shard := c.shards[hash]
+ c.mu.RUnlock()
+
+ return shard, nil
+}
+
+func (c *ringShards) GetByHash(name string) (*ringShard, error) {
+ if name == "" {
+ return c.Random()
+ }
+
+ c.mu.RLock()
+ shard := c.shards[name]
+ c.mu.RUnlock()
+ return shard, nil
+}
+
+func (c *ringShards) Random() (*ringShard, error) {
+ return c.GetByKey(strconv.Itoa(rand.Int()))
+}
+
+// heartbeat monitors state of each shard in the ring.
+func (c *ringShards) Heartbeat(frequency time.Duration) {
+ ticker := time.NewTicker(frequency)
+ defer ticker.Stop()
+ for range ticker.C {
+ var rebalance bool
+
+ c.mu.RLock()
+
+ if c.closed {
+ c.mu.RUnlock()
+ break
+ }
+
+ shards := c.list
+ c.mu.RUnlock()
+
+ for _, shard := range shards {
+ err := shard.Client.Ping().Err()
+ if shard.Vote(err == nil || err == pool.ErrPoolTimeout) {
+ internal.Logf("ring shard state changed: %s", shard)
+ rebalance = true
+ }
+ }
+
+ if rebalance {
+ c.rebalance()
+ }
+ }
+}
+
+// rebalance removes dead shards from the Ring.
+func (c *ringShards) rebalance() {
+ hash := consistenthash.New(nreplicas, nil)
+ for name, shard := range c.shards {
+ if shard.IsUp() {
+ hash.Add(name)
+ }
+ }
+
+ c.mu.Lock()
+ c.hash = hash
+ c.mu.Unlock()
+}
+
+func (c *ringShards) Close() error {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
+ if c.closed {
+ return nil
+ }
+ c.closed = true
+
+ var firstErr error
+ for _, shard := range c.shards {
+ if err := shard.Client.Close(); err != nil && firstErr == nil {
+ firstErr = err
+ }
+ }
+ c.hash = nil
+ c.shards = nil
+ c.list = nil
+
+ return firstErr
+}
+
+//------------------------------------------------------------------------------
+
// Ring is a Redis client that uses constistent hashing to distribute
// keys across multiple Redis servers (shards). It's safe for
// concurrent use by multiple goroutines.
@@ -142,33 +291,22 @@ func (shard *ringShard) Vote(up bool) bool {
type Ring struct {
cmdable
- opt *RingOptions
- nreplicas int
+ ctx context.Context
- mu sync.RWMutex
- hash *consistenthash.Map
- shards map[string]*ringShard
- shardsList []*ringShard
+ opt *RingOptions
+ shards *ringShards
+ cmdsInfoCache *cmdsInfoCache
processPipeline func([]Cmder) error
-
- cmdsInfoOnce internal.Once
- cmdsInfo map[string]*CommandInfo
-
- closed bool
}
func NewRing(opt *RingOptions) *Ring {
- const nreplicas = 100
-
opt.init()
ring := &Ring{
- opt: opt,
- nreplicas: nreplicas,
-
- hash: consistenthash.New(nreplicas, nil),
- shards: make(map[string]*ringShard),
+ opt: opt,
+ shards: newRingShards(),
+ cmdsInfoCache: newCmdsInfoCache(),
}
ring.processPipeline = ring.defaultProcessPipeline
ring.cmdable.setProcessor(ring.Process)
@@ -176,21 +314,33 @@ func NewRing(opt *RingOptions) *Ring {
for name, addr := range opt.Addrs {
clopt := opt.clientOptions()
clopt.Addr = addr
- ring.addShard(name, NewClient(clopt))
+ ring.shards.Add(name, NewClient(clopt))
}
- go ring.heartbeat()
+ go ring.shards.Heartbeat(opt.HeartbeatFrequency)
return ring
}
-func (c *Ring) addShard(name string, cl *Client) {
- shard := &ringShard{Client: cl}
- c.mu.Lock()
- c.hash.Add(name)
- c.shards[name] = shard
- c.shardsList = append(c.shardsList, shard)
- c.mu.Unlock()
+func (c *Ring) Context() context.Context {
+ if c.ctx != nil {
+ return c.ctx
+ }
+ return context.Background()
+}
+
+func (c *Ring) WithContext(ctx context.Context) *Ring {
+ if ctx == nil {
+ panic("nil context")
+ }
+ c2 := c.copy()
+ c2.ctx = ctx
+ return c2
+}
+
+func (c *Ring) copy() *Ring {
+ cp := *c
+ return &cp
}
// Options returns read-only Options that were used to create the client.
@@ -204,10 +354,7 @@ func (c *Ring) retryBackoff(attempt int) time.Duration {
// PoolStats returns accumulated connection pool stats.
func (c *Ring) PoolStats() *PoolStats {
- c.mu.RLock()
- shards := c.shardsList
- c.mu.RUnlock()
-
+ shards := c.shards.List()
var acc PoolStats
for _, shard := range shards {
s := shard.Client.connPool.Stats()
@@ -226,7 +373,7 @@ func (c *Ring) Subscribe(channels ...string) *PubSub {
panic("at least one channel is required")
}
- shard, err := c.shardByKey(channels[0])
+ shard, err := c.shards.GetByKey(channels[0])
if err != nil {
// TODO: return PubSub with sticky error
panic(err)
@@ -240,7 +387,7 @@ func (c *Ring) PSubscribe(channels ...string) *PubSub {
panic("at least one channel is required")
}
- shard, err := c.shardByKey(channels[0])
+ shard, err := c.shards.GetByKey(channels[0])
if err != nil {
// TODO: return PubSub with sticky error
panic(err)
@@ -251,10 +398,7 @@ func (c *Ring) PSubscribe(channels ...string) *PubSub {
// ForEachShard concurrently calls the fn on each live shard in the ring.
// It returns the first error if any.
func (c *Ring) ForEachShard(fn func(client *Client) error) error {
- c.mu.RLock()
- shards := c.shardsList
- c.mu.RUnlock()
-
+ shards := c.shards.List()
var wg sync.WaitGroup
errCh := make(chan error, 1)
for _, shard := range shards {
@@ -285,81 +429,38 @@ func (c *Ring) ForEachShard(fn func(client *Client) error) error {
}
func (c *Ring) cmdInfo(name string) *CommandInfo {
- err := c.cmdsInfoOnce.Do(func() error {
- c.mu.RLock()
- shards := c.shardsList
- c.mu.RUnlock()
-
- var firstErr error
+ cmdsInfo, err := c.cmdsInfoCache.Do(func() (map[string]*CommandInfo, error) {
+ shards := c.shards.List()
+ firstErr := errRingShardsDown
for _, shard := range shards {
cmdsInfo, err := shard.Client.Command().Result()
if err == nil {
- c.cmdsInfo = cmdsInfo
- return nil
+ return cmdsInfo, nil
}
if firstErr == nil {
firstErr = err
}
}
- return firstErr
+ return nil, firstErr
})
if err != nil {
return nil
}
- if c.cmdsInfo == nil {
- return nil
- }
- info := c.cmdsInfo[name]
+ info := cmdsInfo[name]
if info == nil {
internal.Logf("info for cmd=%s not found", name)
}
return info
}
-func (c *Ring) shardByKey(key string) (*ringShard, error) {
- key = hashtag.Key(key)
-
- c.mu.RLock()
-
- if c.closed {
- c.mu.RUnlock()
- return nil, pool.ErrClosed
- }
-
- name := c.hash.Get(key)
- if name == "" {
- c.mu.RUnlock()
- return nil, errRingShardsDown
- }
-
- shard := c.shards[name]
- c.mu.RUnlock()
- return shard, nil
-}
-
-func (c *Ring) randomShard() (*ringShard, error) {
- return c.shardByKey(strconv.Itoa(rand.Int()))
-}
-
-func (c *Ring) shardByName(name string) (*ringShard, error) {
- if name == "" {
- return c.randomShard()
- }
-
- c.mu.RLock()
- shard := c.shards[name]
- c.mu.RUnlock()
- return shard, nil
-}
-
func (c *Ring) cmdShard(cmd Cmder) (*ringShard, error) {
cmdInfo := c.cmdInfo(cmd.Name())
pos := cmdFirstKeyPos(cmd, cmdInfo)
if pos == 0 {
- return c.randomShard()
+ return c.shards.Random()
}
firstKey := cmd.stringArg(pos)
- return c.shardByKey(firstKey)
+ return c.shards.GetByKey(firstKey)
}
func (c *Ring) WrapProcess(fn func(oldProcess func(cmd Cmder) error) func(cmd Cmder) error) {
@@ -378,77 +479,6 @@ func (c *Ring) Process(cmd Cmder) error {
return shard.Client.Process(cmd)
}
-// rebalance removes dead shards from the Ring.
-func (c *Ring) rebalance() {
- hash := consistenthash.New(c.nreplicas, nil)
- for name, shard := range c.shards {
- if shard.IsUp() {
- hash.Add(name)
- }
- }
-
- c.mu.Lock()
- c.hash = hash
- c.mu.Unlock()
-}
-
-// heartbeat monitors state of each shard in the ring.
-func (c *Ring) heartbeat() {
- ticker := time.NewTicker(c.opt.HeartbeatFrequency)
- defer ticker.Stop()
- for range ticker.C {
- var rebalance bool
-
- c.mu.RLock()
-
- if c.closed {
- c.mu.RUnlock()
- break
- }
-
- shards := c.shardsList
- c.mu.RUnlock()
-
- for _, shard := range shards {
- err := shard.Client.Ping().Err()
- if shard.Vote(err == nil || err == pool.ErrPoolTimeout) {
- internal.Logf("ring shard state changed: %s", shard)
- rebalance = true
- }
- }
-
- if rebalance {
- c.rebalance()
- }
- }
-}
-
-// Close closes the ring client, releasing any open resources.
-//
-// 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 {
- c.mu.Lock()
- defer c.mu.Unlock()
-
- if c.closed {
- return nil
- }
- c.closed = true
-
- var firstErr error
- for _, shard := range c.shards {
- if err := shard.Client.Close(); err != nil && firstErr == nil {
- firstErr = err
- }
- }
- c.hash = nil
- c.shards = nil
- c.shardsList = nil
-
- return firstErr
-}
-
func (c *Ring) Pipeline() Pipeliner {
pipe := Pipeline{
exec: c.processPipeline,
@@ -471,11 +501,11 @@ func (c *Ring) defaultProcessPipeline(cmds []Cmder) error {
cmdsMap := make(map[string][]Cmder)
for _, cmd := range cmds {
cmdInfo := c.cmdInfo(cmd.Name())
- name := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo))
- if name != "" {
- name = c.hash.Get(hashtag.Key(name))
+ hash := cmd.stringArg(cmdFirstKeyPos(cmd, cmdInfo))
+ if hash != "" {
+ hash = c.shards.Hash(hashtag.Key(hash))
}
- cmdsMap[name] = append(cmdsMap[name], cmd)
+ cmdsMap[hash] = append(cmdsMap[hash], cmd)
}
for attempt := 0; attempt <= c.opt.MaxRetries; attempt++ {
@@ -485,8 +515,8 @@ func (c *Ring) defaultProcessPipeline(cmds []Cmder) error {
var failedCmdsMap map[string][]Cmder
- for name, cmds := range cmdsMap {
- shard, err := c.shardByName(name)
+ for hash, cmds := range cmdsMap {
+ shard, err := c.shards.GetByHash(hash)
if err != nil {
setCmdsErr(cmds, err)
continue
@@ -509,7 +539,7 @@ func (c *Ring) defaultProcessPipeline(cmds []Cmder) error {
if failedCmdsMap == nil {
failedCmdsMap = make(map[string][]Cmder)
}
- failedCmdsMap[name] = cmds
+ failedCmdsMap[hash] = cmds
}
}
@@ -529,3 +559,11 @@ func (c *Ring) TxPipeline() Pipeliner {
func (c *Ring) TxPipelined(fn func(Pipeliner) error) ([]Cmder, error) {
panic("not implemented")
}
+
+// Close closes the ring client, releasing any open resources.
+//
+// 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 {
+ return c.shards.Close()
+}
diff --git a/vendor/github.com/go-redis/redis/ring_test.go b/vendor/github.com/go-redis/redis/ring_test.go
deleted file mode 100644
index 0cad4298b..000000000
--- a/vendor/github.com/go-redis/redis/ring_test.go
+++ /dev/null
@@ -1,193 +0,0 @@
-package redis_test
-
-import (
- "crypto/rand"
- "fmt"
- "time"
-
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("Redis Ring", func() {
- const heartbeat = 100 * time.Millisecond
-
- var ring *redis.Ring
-
- setRingKeys := func() {
- for i := 0; i < 100; i++ {
- err := ring.Set(fmt.Sprintf("key%d", i), "value", 0).Err()
- Expect(err).NotTo(HaveOccurred())
- }
- }
-
- BeforeEach(func() {
- opt := redisRingOptions()
- opt.HeartbeatFrequency = heartbeat
- ring = redis.NewRing(opt)
-
- err := ring.ForEachShard(func(cl *redis.Client) error {
- return cl.FlushDB().Err()
- })
- Expect(err).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- Expect(ring.Close()).NotTo(HaveOccurred())
- })
-
- It("distributes keys", func() {
- setRingKeys()
-
- // Both shards should have some keys now.
- Expect(ringShard1.Info().Val()).To(ContainSubstring("keys=57"))
- Expect(ringShard2.Info().Val()).To(ContainSubstring("keys=43"))
- })
-
- It("distributes keys when using EVAL", func() {
- script := redis.NewScript(`
- local r = redis.call('SET', KEYS[1], ARGV[1])
- return r
- `)
-
- var key string
- for i := 0; i < 100; i++ {
- key = fmt.Sprintf("key%d", i)
- err := script.Run(ring, []string{key}, "value").Err()
- Expect(err).NotTo(HaveOccurred())
- }
-
- Expect(ringShard1.Info().Val()).To(ContainSubstring("keys=57"))
- Expect(ringShard2.Info().Val()).To(ContainSubstring("keys=43"))
- })
-
- It("uses single shard when one of the shards is down", func() {
- // Stop ringShard2.
- Expect(ringShard2.Close()).NotTo(HaveOccurred())
-
- // Ring needs 3 * heartbeat time to detect that node is down.
- // Give it more to be sure.
- time.Sleep(2 * 3 * heartbeat)
-
- setRingKeys()
-
- // RingShard1 should have all keys.
- Expect(ringShard1.Info().Val()).To(ContainSubstring("keys=100"))
-
- // Start ringShard2.
- var err error
- ringShard2, err = startRedis(ringShard2Port)
- Expect(err).NotTo(HaveOccurred())
-
- // Wait for ringShard2 to come up.
- Eventually(func() error {
- return ringShard2.Ping().Err()
- }, "1s").ShouldNot(HaveOccurred())
-
- // Ring needs heartbeat time to detect that node is up.
- // Give it more to be sure.
- time.Sleep(heartbeat + heartbeat)
-
- setRingKeys()
-
- // RingShard2 should have its keys.
- Expect(ringShard2.Info().Val()).To(ContainSubstring("keys=43"))
- })
-
- It("supports hash tags", func() {
- for i := 0; i < 100; i++ {
- err := ring.Set(fmt.Sprintf("key%d{tag}", i), "value", 0).Err()
- Expect(err).NotTo(HaveOccurred())
- }
-
- Expect(ringShard1.Info().Val()).ToNot(ContainSubstring("keys="))
- Expect(ringShard2.Info().Val()).To(ContainSubstring("keys=100"))
- })
-
- Describe("pipeline", func() {
- It("distributes keys", func() {
- pipe := ring.Pipeline()
- for i := 0; i < 100; i++ {
- err := pipe.Set(fmt.Sprintf("key%d", i), "value", 0).Err()
- Expect(err).NotTo(HaveOccurred())
- }
- cmds, err := pipe.Exec()
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(100))
- Expect(pipe.Close()).NotTo(HaveOccurred())
-
- for _, cmd := range cmds {
- Expect(cmd.Err()).NotTo(HaveOccurred())
- Expect(cmd.(*redis.StatusCmd).Val()).To(Equal("OK"))
- }
-
- // Both shards should have some keys now.
- Expect(ringShard1.Info().Val()).To(ContainSubstring("keys=57"))
- Expect(ringShard2.Info().Val()).To(ContainSubstring("keys=43"))
- })
-
- It("is consistent with ring", func() {
- var keys []string
- for i := 0; i < 100; i++ {
- key := make([]byte, 64)
- _, err := rand.Read(key)
- Expect(err).NotTo(HaveOccurred())
- keys = append(keys, string(key))
- }
-
- _, err := ring.Pipelined(func(pipe redis.Pipeliner) error {
- for _, key := range keys {
- pipe.Set(key, "value", 0).Err()
- }
- return nil
- })
- Expect(err).NotTo(HaveOccurred())
-
- for _, key := range keys {
- val, err := ring.Get(key).Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("value"))
- }
- })
-
- It("supports hash tags", func() {
- _, err := ring.Pipelined(func(pipe redis.Pipeliner) error {
- for i := 0; i < 100; i++ {
- pipe.Set(fmt.Sprintf("key%d{tag}", i), "value", 0).Err()
- }
- return nil
- })
- Expect(err).NotTo(HaveOccurred())
-
- Expect(ringShard1.Info().Val()).ToNot(ContainSubstring("keys="))
- Expect(ringShard2.Info().Val()).To(ContainSubstring("keys=100"))
- })
- })
-})
-
-var _ = Describe("empty Redis Ring", func() {
- var ring *redis.Ring
-
- BeforeEach(func() {
- ring = redis.NewRing(&redis.RingOptions{})
- })
-
- AfterEach(func() {
- Expect(ring.Close()).NotTo(HaveOccurred())
- })
-
- It("returns an error", func() {
- err := ring.Ping().Err()
- Expect(err).To(MatchError("redis: all ring shards are down"))
- })
-
- It("pipeline returns an error", func() {
- _, err := ring.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Ping()
- return nil
- })
- Expect(err).To(MatchError("redis: all ring shards are down"))
- })
-})
diff --git a/vendor/github.com/go-redis/redis/script.go b/vendor/github.com/go-redis/redis/script.go
index 74135f5a5..09f36d932 100644
--- a/vendor/github.com/go-redis/redis/script.go
+++ b/vendor/github.com/go-redis/redis/script.go
@@ -10,7 +10,7 @@ import (
type scripter interface {
Eval(script string, keys []string, args ...interface{}) *Cmd
EvalSha(sha1 string, keys []string, args ...interface{}) *Cmd
- ScriptExists(scripts ...string) *BoolSliceCmd
+ ScriptExists(hashes ...string) *BoolSliceCmd
ScriptLoad(script string) *StringCmd
}
@@ -40,7 +40,7 @@ func (s *Script) Load(c scripter) *StringCmd {
}
func (s *Script) Exists(c scripter) *BoolSliceCmd {
- return c.ScriptExists(s.src)
+ return c.ScriptExists(s.hash)
}
func (s *Script) Eval(c scripter, keys []string, args ...interface{}) *Cmd {
diff --git a/vendor/github.com/go-redis/redis/sentinel_test.go b/vendor/github.com/go-redis/redis/sentinel_test.go
deleted file mode 100644
index c67713cd0..000000000
--- a/vendor/github.com/go-redis/redis/sentinel_test.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package redis_test
-
-import (
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("Sentinel", func() {
- var client *redis.Client
-
- BeforeEach(func() {
- client = redis.NewFailoverClient(&redis.FailoverOptions{
- MasterName: sentinelName,
- SentinelAddrs: []string{":" + sentinelPort},
- })
- Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("should facilitate failover", func() {
- // Set value on master.
- err := client.Set("foo", "master", 0).Err()
- Expect(err).NotTo(HaveOccurred())
-
- // Verify.
- val, err := sentinelMaster.Get("foo").Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(val).To(Equal("master"))
-
- // Create subscription.
- ch := client.Subscribe("foo").Channel()
-
- // Wait until replicated.
- Eventually(func() string {
- return sentinelSlave1.Get("foo").Val()
- }, "1s", "100ms").Should(Equal("master"))
- Eventually(func() string {
- return sentinelSlave2.Get("foo").Val()
- }, "1s", "100ms").Should(Equal("master"))
-
- // Wait until slaves are picked up by sentinel.
- Eventually(func() string {
- return sentinel.Info().Val()
- }, "10s", "100ms").Should(ContainSubstring("slaves=2"))
-
- // Kill master.
- sentinelMaster.Shutdown()
- Eventually(func() error {
- return sentinelMaster.Ping().Err()
- }, "5s", "100ms").Should(HaveOccurred())
-
- // Wait for Redis sentinel to elect new master.
- Eventually(func() string {
- return sentinelSlave1.Info().Val() + sentinelSlave2.Info().Val()
- }, "30s", "1s").Should(ContainSubstring("role:master"))
-
- // Check that client picked up new master.
- Eventually(func() error {
- return client.Get("foo").Err()
- }, "5s", "100ms").ShouldNot(HaveOccurred())
-
- // Publish message to check if subscription is renewed.
- err = client.Publish("foo", "hello").Err()
- Expect(err).NotTo(HaveOccurred())
-
- var msg *redis.Message
- Eventually(ch).Should(Receive(&msg))
- Expect(msg.Channel).To(Equal("foo"))
- Expect(msg.Payload).To(Equal("hello"))
- })
-
- It("supports DB selection", func() {
- Expect(client.Close()).NotTo(HaveOccurred())
-
- client = redis.NewFailoverClient(&redis.FailoverOptions{
- MasterName: sentinelName,
- SentinelAddrs: []string{":" + sentinelPort},
- DB: 1,
- })
- err := client.Ping().Err()
- Expect(err).NotTo(HaveOccurred())
- })
-})
diff --git a/vendor/github.com/go-redis/redis/testdata/redis.conf b/vendor/github.com/go-redis/redis/testdata/redis.conf
deleted file mode 100644
index 235b2954a..000000000
--- a/vendor/github.com/go-redis/redis/testdata/redis.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-# Minimal redis.conf
-
-port 6379
-daemonize no
-dir .
-save ""
-appendonly yes
-cluster-config-file nodes.conf
-cluster-node-timeout 30000
-maxclients 1001 \ No newline at end of file
diff --git a/vendor/github.com/go-redis/redis/tx.go b/vendor/github.com/go-redis/redis/tx.go
index 26c29bef5..6a753b6a0 100644
--- a/vendor/github.com/go-redis/redis/tx.go
+++ b/vendor/github.com/go-redis/redis/tx.go
@@ -1,12 +1,12 @@
package redis
import (
- "github.com/go-redis/redis/internal"
"github.com/go-redis/redis/internal/pool"
+ "github.com/go-redis/redis/internal/proto"
)
// TxFailedErr transaction redis failed.
-const TxFailedErr = internal.RedisError("redis: transaction failed")
+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
diff --git a/vendor/github.com/go-redis/redis/tx_test.go b/vendor/github.com/go-redis/redis/tx_test.go
deleted file mode 100644
index de597ff06..000000000
--- a/vendor/github.com/go-redis/redis/tx_test.go
+++ /dev/null
@@ -1,151 +0,0 @@
-package redis_test
-
-import (
- "strconv"
- "sync"
-
- "github.com/go-redis/redis"
-
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-var _ = Describe("Tx", func() {
- var client *redis.Client
-
- BeforeEach(func() {
- client = redis.NewClient(redisOptions())
- Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
- })
-
- AfterEach(func() {
- Expect(client.Close()).NotTo(HaveOccurred())
- })
-
- It("should Watch", func() {
- var incr func(string) error
-
- // Transactionally increments key using GET and SET commands.
- incr = func(key string) error {
- err := client.Watch(func(tx *redis.Tx) error {
- n, err := tx.Get(key).Int64()
- if err != nil && err != redis.Nil {
- return err
- }
-
- _, err = tx.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Set(key, strconv.FormatInt(n+1, 10), 0)
- return nil
- })
- return err
- }, key)
- if err == redis.TxFailedErr {
- return incr(key)
- }
- return err
- }
-
- var wg sync.WaitGroup
- for i := 0; i < 100; i++ {
- wg.Add(1)
- go func() {
- defer GinkgoRecover()
- defer wg.Done()
-
- err := incr("key")
- Expect(err).NotTo(HaveOccurred())
- }()
- }
- wg.Wait()
-
- n, err := client.Get("key").Int64()
- Expect(err).NotTo(HaveOccurred())
- Expect(n).To(Equal(int64(100)))
- })
-
- It("should discard", func() {
- err := client.Watch(func(tx *redis.Tx) error {
- cmds, err := tx.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Set("key1", "hello1", 0)
- pipe.Discard()
- pipe.Set("key2", "hello2", 0)
- return nil
- })
- Expect(err).NotTo(HaveOccurred())
- Expect(cmds).To(HaveLen(1))
- return err
- }, "key1", "key2")
- Expect(err).NotTo(HaveOccurred())
-
- get := client.Get("key1")
- Expect(get.Err()).To(Equal(redis.Nil))
- Expect(get.Val()).To(Equal(""))
-
- get = client.Get("key2")
- Expect(get.Err()).NotTo(HaveOccurred())
- Expect(get.Val()).To(Equal("hello2"))
- })
-
- It("returns no error when there are no commands", func() {
- err := client.Watch(func(tx *redis.Tx) error {
- _, err := tx.Pipelined(func(redis.Pipeliner) error { return nil })
- return err
- })
- Expect(err).NotTo(HaveOccurred())
-
- v, err := client.Ping().Result()
- Expect(err).NotTo(HaveOccurred())
- Expect(v).To(Equal("PONG"))
- })
-
- It("should exec bulks", func() {
- const N = 20000
-
- err := client.Watch(func(tx *redis.Tx) error {
- cmds, err := tx.Pipelined(func(pipe redis.Pipeliner) error {
- for i := 0; i < N; i++ {
- pipe.Incr("key")
- }
- return nil
- })
- Expect(err).NotTo(HaveOccurred())
- Expect(len(cmds)).To(Equal(N))
- for _, cmd := range cmds {
- Expect(cmd.Err()).NotTo(HaveOccurred())
- }
- return err
- })
- Expect(err).NotTo(HaveOccurred())
-
- num, err := client.Get("key").Int64()
- Expect(err).NotTo(HaveOccurred())
- Expect(num).To(Equal(int64(N)))
- })
-
- It("should recover from bad connection", func() {
- // Put bad connection in the pool.
- cn, _, err := client.Pool().Get()
- Expect(err).NotTo(HaveOccurred())
-
- cn.SetNetConn(&badConn{})
- err = client.Pool().Put(cn)
- Expect(err).NotTo(HaveOccurred())
-
- do := func() error {
- err := client.Watch(func(tx *redis.Tx) error {
- _, err := tx.Pipelined(func(pipe redis.Pipeliner) error {
- pipe.Ping()
- return nil
- })
- return err
- })
- return err
- }
-
- err = do()
- Expect(err).To(MatchError("bad connection"))
-
- err = do()
- Expect(err).NotTo(HaveOccurred())
- })
-})
diff --git a/vendor/github.com/go-redis/redis/universal.go b/vendor/github.com/go-redis/redis/universal.go
index ea42f6984..fde3c4150 100644
--- a/vendor/github.com/go-redis/redis/universal.go
+++ b/vendor/github.com/go-redis/redis/universal.go
@@ -114,6 +114,7 @@ func (o *UniversalOptions) simple() *Options {
type UniversalClient interface {
Cmdable
Process(cmd Cmder) error
+ WrapProcess(fn func(oldProcess func(cmd Cmder) error) func(cmd Cmder) error)
Subscribe(channels ...string) *PubSub
PSubscribe(channels ...string) *PubSub
Close() error
diff --git a/vendor/github.com/go-redis/redis/universal_test.go b/vendor/github.com/go-redis/redis/universal_test.go
deleted file mode 100644
index 2a0850dea..000000000
--- a/vendor/github.com/go-redis/redis/universal_test.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package redis_test
-
-import (
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-
- "github.com/go-redis/redis"
-)
-
-var _ = Describe("UniversalClient", func() {
- var client redis.UniversalClient
-
- AfterEach(func() {
- if client != nil {
- Expect(client.Close()).To(Succeed())
- }
- })
-
- It("should connect to failover servers", func() {
- client = redis.NewUniversalClient(&redis.UniversalOptions{
- MasterName: sentinelName,
- Addrs: []string{":" + sentinelPort},
- })
- Expect(client.Ping().Err()).NotTo(HaveOccurred())
- })
-
- It("should connect to simple servers", func() {
- client = redis.NewUniversalClient(&redis.UniversalOptions{
- Addrs: []string{redisAddr},
- })
- Expect(client.Ping().Err()).NotTo(HaveOccurred())
- })
-
- It("should connect to clusters", func() {
- client = redis.NewUniversalClient(&redis.UniversalOptions{
- Addrs: cluster.addrs(),
- })
- Expect(client.Ping().Err()).NotTo(HaveOccurred())
- })
-
-})