Skip to content

Commit 655eaaa

Browse files
authored
Merge pull request #1473 from go-redis/feature/failover-cluster-client
Feature/failover cluster client
2 parents b273d2b + 690d9a9 commit 655eaaa

File tree

11 files changed

+303
-121
lines changed

11 files changed

+303
-121
lines changed

bench_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ func BenchmarkClusterPing(b *testing.B) {
259259
if err := startCluster(ctx, cluster); err != nil {
260260
b.Fatal(err)
261261
}
262-
defer stopCluster(cluster)
262+
defer cluster.Close()
263263

264264
client := cluster.newClusterClient(ctx, redisClusterOptions())
265265
defer client.Close()
@@ -286,7 +286,7 @@ func BenchmarkClusterSetString(b *testing.B) {
286286
if err := startCluster(ctx, cluster); err != nil {
287287
b.Fatal(err)
288288
}
289-
defer stopCluster(cluster)
289+
defer cluster.Close()
290290

291291
client := cluster.newClusterClient(ctx, redisClusterOptions())
292292
defer client.Close()
@@ -315,7 +315,7 @@ func BenchmarkClusterReloadState(b *testing.B) {
315315
if err := startCluster(ctx, cluster); err != nil {
316316
b.Fatal(err)
317317
}
318-
defer stopCluster(cluster)
318+
defer cluster.Close()
319319

320320
client := cluster.newClusterClient(ctx, redisClusterOptions())
321321
defer client.Close()

cluster.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ type ClusterOptions struct {
4949
// and load-balance read/write operations between master and slaves.
5050
// It can use service like ZooKeeper to maintain configuration information
5151
// and Cluster.ReloadState to manually trigger state reloading.
52-
ClusterSlots func() ([]ClusterSlot, error)
52+
ClusterSlots func(context.Context) ([]ClusterSlot, error)
5353

5454
// Following options are copied from Options struct.
5555

@@ -987,7 +987,7 @@ func (c *ClusterClient) PoolStats() *PoolStats {
987987

988988
func (c *ClusterClient) loadState(ctx context.Context) (*clusterState, error) {
989989
if c.opt.ClusterSlots != nil {
990-
slots, err := c.opt.ClusterSlots()
990+
slots, err := c.opt.ClusterSlots(ctx)
991991
if err != nil {
992992
return nil, err
993993
}

cluster_test.go

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ func (s *clusterScenario) newClusterClient(
8080
return client
8181
}
8282

83+
func (s *clusterScenario) Close() error {
84+
for _, port := range s.ports {
85+
processes[port].Close()
86+
delete(processes, port)
87+
}
88+
return nil
89+
}
90+
8391
func startCluster(ctx context.Context, scenario *clusterScenario) error {
8492
// Start processes and collect node ids
8593
for pos, port := range scenario.ports {
@@ -221,20 +229,6 @@ func slotEqual(s1, s2 redis.ClusterSlot) bool {
221229
return true
222230
}
223231

224-
func stopCluster(scenario *clusterScenario) error {
225-
for _, client := range scenario.clients {
226-
if err := client.Close(); err != nil {
227-
return err
228-
}
229-
}
230-
for _, process := range scenario.processes {
231-
if err := process.Close(); err != nil {
232-
return err
233-
}
234-
}
235-
return nil
236-
}
237-
238232
//------------------------------------------------------------------------------
239233

240234
var _ = Describe("ClusterClient", func() {
@@ -911,7 +905,7 @@ var _ = Describe("ClusterClient", func() {
911905
failover = true
912906

913907
opt = redisClusterOptions()
914-
opt.ClusterSlots = func() ([]redis.ClusterSlot, error) {
908+
opt.ClusterSlots = func(ctx context.Context) ([]redis.ClusterSlot, error) {
915909
slots := []redis.ClusterSlot{{
916910
Start: 0,
917911
End: 4999,
@@ -965,7 +959,7 @@ var _ = Describe("ClusterClient", func() {
965959

966960
opt = redisClusterOptions()
967961
opt.RouteRandomly = true
968-
opt.ClusterSlots = func() ([]redis.ClusterSlot, error) {
962+
opt.ClusterSlots = func(ctx context.Context) ([]redis.ClusterSlot, error) {
969963
slots := []redis.ClusterSlot{{
970964
Start: 0,
971965
End: 4999,

commands.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2307,7 +2307,7 @@ func (c cmdable) SlaveOf(ctx context.Context, host, port string) *StatusCmd {
23072307
return cmd
23082308
}
23092309

2310-
func (c cmdable) SlowLog(ctx context.Context, num int64) *SlowLogCmd {
2310+
func (c cmdable) SlowLogGet(ctx context.Context, num int64) *SlowLogCmd {
23112311
n := strconv.FormatInt(num, 10)
23122312
cmd := NewSlowLogCmd(context.Background(), "slowlog", "get", n)
23132313
_ = c(ctx, cmd)

commands_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4014,7 +4014,7 @@ var _ = Describe("Commands", func() {
40144014
})
40154015
})
40164016

4017-
Describe("SlowLog", func() {
4017+
Describe("SlowLogGet", func() {
40184018
It("returns slow query result", func() {
40194019
const key = "slowlog-log-slower-than"
40204020

@@ -4027,9 +4027,9 @@ var _ = Describe("Commands", func() {
40274027

40284028
client.Set(ctx, "test", "true", 0)
40294029

4030-
result, err := client.SlowLog(ctx, -1).Result()
4030+
result, err := client.SlowLogGet(ctx, -1).Result()
40314031
Expect(err).NotTo(HaveOccurred())
4032-
Expect(len(result)).To(Equal(2))
4032+
Expect(len(result)).NotTo(BeZero())
40334033
})
40344034
})
40354035
})

example_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func ExampleNewClusterClient_manualSetup() {
8080
// clusterSlots returns cluster slots information.
8181
// It can use service like ZooKeeper to maintain configuration information
8282
// and Cluster.ReloadState to manually trigger state reloading.
83-
clusterSlots := func() ([]redis.ClusterSlot, error) {
83+
clusterSlots := func(ctx context.Context) ([]redis.ClusterSlot, error) {
8484
slots := []redis.ClusterSlot{
8585
// First node with 1 master and 1 slave.
8686
{
@@ -511,7 +511,7 @@ func ExampleNewUniversalClient_cluster() {
511511
rdb.Ping(ctx)
512512
}
513513

514-
func ExampleClient_SlowLog() {
514+
func ExampleClient_SlowLogGet() {
515515
const key = "slowlog-log-slower-than"
516516

517517
old := rdb.ConfigGet(ctx, key).Val()
@@ -524,7 +524,7 @@ func ExampleClient_SlowLog() {
524524

525525
rdb.Set(ctx, "test", "true", 0)
526526

527-
result, err := rdb.SlowLog(ctx, -1).Result()
527+
result, err := rdb.SlowLogGet(ctx, -1).Result()
528528
if err != nil {
529529
panic(err)
530530
}

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
4040
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
4141
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
4242
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
43+
github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4=
4344
github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
4445
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
4546
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=

main_test.go

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,14 @@ const (
4141
)
4242

4343
var (
44+
sentinelAddrs = []string{":" + sentinelPort1, ":" + sentinelPort2, ":" + sentinelPort3}
45+
46+
processes map[string]*redisProcess
47+
4448
redisMain *redisProcess
4549
ringShard1, ringShard2, ringShard3 *redisProcess
4650
sentinelMaster, sentinelSlave1, sentinelSlave2 *redisProcess
4751
sentinel1, sentinel2, sentinel3 *redisProcess
48-
49-
sentinelAddrs = []string{":" + sentinelPort1, ":" + sentinelPort2, ":" + sentinelPort3}
5052
)
5153

5254
var cluster = &clusterScenario{
@@ -56,6 +58,13 @@ var cluster = &clusterScenario{
5658
clients: make(map[string]*redis.Client, 6),
5759
}
5860

61+
func registerProcess(port string, p *redisProcess) {
62+
if processes == nil {
63+
processes = make(map[string]*redisProcess)
64+
}
65+
processes[port] = p
66+
}
67+
5968
var _ = BeforeSuite(func() {
6069
var err error
6170

@@ -95,20 +104,12 @@ var _ = BeforeSuite(func() {
95104
})
96105

97106
var _ = AfterSuite(func() {
98-
Expect(redisMain.Close()).NotTo(HaveOccurred())
107+
Expect(cluster.Close()).NotTo(HaveOccurred())
99108

100-
Expect(ringShard1.Close()).NotTo(HaveOccurred())
101-
Expect(ringShard2.Close()).NotTo(HaveOccurred())
102-
Expect(ringShard3.Close()).NotTo(HaveOccurred())
103-
104-
Expect(sentinel1.Close()).NotTo(HaveOccurred())
105-
Expect(sentinel2.Close()).NotTo(HaveOccurred())
106-
Expect(sentinel3.Close()).NotTo(HaveOccurred())
107-
Expect(sentinelSlave1.Close()).NotTo(HaveOccurred())
108-
Expect(sentinelSlave2.Close()).NotTo(HaveOccurred())
109-
Expect(sentinelMaster.Close()).NotTo(HaveOccurred())
110-
111-
Expect(stopCluster(cluster)).NotTo(HaveOccurred())
109+
for _, p := range processes {
110+
Expect(p.Close()).NotTo(HaveOccurred())
111+
}
112+
processes = nil
112113
})
113114

114115
func TestGinkgoSuite(t *testing.T) {
@@ -308,23 +309,29 @@ func startRedis(port string, args ...string) (*redisProcess, error) {
308309
process.Kill()
309310
return nil, err
310311
}
311-
return &redisProcess{process, client}, err
312+
313+
p := &redisProcess{process, client}
314+
registerProcess(port, p)
315+
return p, err
312316
}
313317

314318
func startSentinel(port, masterName, masterPort string) (*redisProcess, error) {
315319
dir, err := redisDir(port)
316320
if err != nil {
317321
return nil, err
318322
}
323+
319324
process, err := execCmd(redisServerBin, os.DevNull, "--sentinel", "--port", port, "--dir", dir)
320325
if err != nil {
321326
return nil, err
322327
}
328+
323329
client, err := connectTo(port)
324330
if err != nil {
325331
process.Kill()
326332
return nil, err
327333
}
334+
328335
for _, cmd := range []*redis.StatusCmd{
329336
redis.NewStatusCmd(ctx, "SENTINEL", "MONITOR", masterName, "127.0.0.1", masterPort, "2"),
330337
redis.NewStatusCmd(ctx, "SENTINEL", "SET", masterName, "down-after-milliseconds", "500"),
@@ -337,7 +344,10 @@ func startSentinel(port, masterName, masterPort string) (*redisProcess, error) {
337344
return nil, err
338345
}
339346
}
340-
return &redisProcess{process, client}, nil
347+
348+
p := &redisProcess{process, client}
349+
registerProcess(port, p)
350+
return p, nil
341351
}
342352

343353
//------------------------------------------------------------------------------

options.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,6 @@ type Options struct {
104104
// Enables read only queries on slave nodes.
105105
readOnly bool
106106

107-
// Enables read only queries on redis replicas in sentinel mode
108-
sentinelReadOnly bool
109-
110107
// TLS Config to use. When set TLS will be negotiated.
111108
TLSConfig *tls.Config
112109

0 commit comments

Comments
 (0)