Skip to content

Commit a8ab4b9

Browse files
authored
Merge pull request #767 from go-redis/fix/cleanup-tests
cluster: cleanup tests
2 parents 18b2e30 + 5c742ff commit a8ab4b9

File tree

4 files changed

+222
-90
lines changed

4 files changed

+222
-90
lines changed

cluster.go

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"math"
99
"math/rand"
1010
"net"
11+
"strings"
1112
"sync"
1213
"sync/atomic"
1314
"time"
@@ -35,6 +36,7 @@ type ClusterOptions struct {
3536
// Enables read-only commands on slave nodes.
3637
ReadOnly bool
3738
// Allows routing read-only commands to the closest master or slave node.
39+
// It automatically enables ReadOnly.
3840
RouteByLatency bool
3941
// Allows routing read-only commands to the random master or slave node.
4042
RouteRandomly bool
@@ -150,6 +152,10 @@ func newClusterNode(clOpt *ClusterOptions, addr string) *clusterNode {
150152
return &node
151153
}
152154

155+
func (n *clusterNode) String() string {
156+
return n.Client.String()
157+
}
158+
153159
func (n *clusterNode) Close() error {
154160
return n.Client.Close()
155161
}
@@ -379,15 +385,17 @@ func (c *clusterNodes) Random() (*clusterNode, error) {
379385

380386
type clusterState struct {
381387
nodes *clusterNodes
382-
masters []*clusterNode
383-
slaves []*clusterNode
388+
Masters []*clusterNode
389+
Slaves []*clusterNode
384390

385391
slots [][]*clusterNode
386392

387393
generation uint32
388394
}
389395

390-
func newClusterState(nodes *clusterNodes, slots []ClusterSlot, origin string) (*clusterState, error) {
396+
func newClusterState(
397+
nodes *clusterNodes, slots []ClusterSlot, origin string,
398+
) (*clusterState, error) {
391399
c := clusterState{
392400
nodes: nodes,
393401
generation: nodes.NextGeneration(),
@@ -413,9 +421,9 @@ func newClusterState(nodes *clusterNodes, slots []ClusterSlot, origin string) (*
413421
nodes = append(nodes, node)
414422

415423
if i == 0 {
416-
c.masters = appendNode(c.masters, node)
424+
c.Masters = appendUniqueNode(c.Masters, node)
417425
} else {
418-
c.slaves = appendNode(c.slaves, node)
426+
c.Slaves = appendUniqueNode(c.Slaves, node)
419427
}
420428
}
421429

@@ -497,6 +505,28 @@ func (c *clusterState) slotNodes(slot int) []*clusterNode {
497505
return nil
498506
}
499507

508+
func (c *clusterState) IsConsistent() bool {
509+
if len(c.Masters) > len(c.Slaves) {
510+
return false
511+
}
512+
513+
for _, master := range c.Masters {
514+
s := master.Client.Info("replication").Val()
515+
if !strings.Contains(s, "role:master") {
516+
return false
517+
}
518+
}
519+
520+
for _, slave := range c.Slaves {
521+
s := slave.Client.Info("replication").Val()
522+
if !strings.Contains(s, "role:slave") {
523+
return false
524+
}
525+
}
526+
527+
return true
528+
}
529+
500530
//------------------------------------------------------------------------------
501531

502532
type clusterStateHolder struct {
@@ -516,7 +546,18 @@ func newClusterStateHolder(fn func() (*clusterState, error)) *clusterStateHolder
516546
}
517547
}
518548

519-
func (c *clusterStateHolder) Load() (*clusterState, error) {
549+
func (c *clusterStateHolder) Reload() (*clusterState, error) {
550+
state, err := c.reload()
551+
if err != nil {
552+
return nil, err
553+
}
554+
if !state.IsConsistent() {
555+
c.LazyReload()
556+
}
557+
return state, nil
558+
}
559+
560+
func (c *clusterStateHolder) reload() (*clusterState, error) {
520561
state, err := c.load()
521562
if err != nil {
522563
c.lastErrMu.Lock()
@@ -535,9 +576,15 @@ func (c *clusterStateHolder) LazyReload() {
535576
go func() {
536577
defer atomic.StoreUint32(&c.reloading, 0)
537578

538-
_, err := c.Load()
539-
if err == nil {
540-
time.Sleep(time.Second)
579+
for {
580+
state, err := c.reload()
581+
if err != nil {
582+
return
583+
}
584+
time.Sleep(100 * time.Millisecond)
585+
if state.IsConsistent() {
586+
return
587+
}
541588
}
542589
}()
543590
}
@@ -596,7 +643,7 @@ func NewClusterClient(opt *ClusterOptions) *ClusterClient {
596643

597644
c.cmdable.setProcessor(c.Process)
598645

599-
_, _ = c.state.Load()
646+
_, _ = c.state.Reload()
600647
if opt.IdleCheckFrequency > 0 {
601648
go c.reaper(opt.IdleCheckFrequency)
602649
}
@@ -890,7 +937,7 @@ func (c *ClusterClient) ForEachMaster(fn func(client *Client) error) error {
890937

891938
var wg sync.WaitGroup
892939
errCh := make(chan error, 1)
893-
for _, master := range state.masters {
940+
for _, master := range state.Masters {
894941
wg.Add(1)
895942
go func(node *clusterNode) {
896943
defer wg.Done()
@@ -923,7 +970,7 @@ func (c *ClusterClient) ForEachSlave(fn func(client *Client) error) error {
923970

924971
var wg sync.WaitGroup
925972
errCh := make(chan error, 1)
926-
for _, slave := range state.slaves {
973+
for _, slave := range state.Slaves {
927974
wg.Add(1)
928975
go func(node *clusterNode) {
929976
defer wg.Done()
@@ -967,11 +1014,11 @@ func (c *ClusterClient) ForEachNode(fn func(client *Client) error) error {
9671014
}
9681015
}
9691016

970-
for _, node := range state.masters {
1017+
for _, node := range state.Masters {
9711018
wg.Add(1)
9721019
go worker(node)
9731020
}
974-
for _, node := range state.slaves {
1021+
for _, node := range state.Slaves {
9751022
wg.Add(1)
9761023
go worker(node)
9771024
}
@@ -994,7 +1041,7 @@ func (c *ClusterClient) PoolStats() *PoolStats {
9941041
return &acc
9951042
}
9961043

997-
for _, node := range state.masters {
1044+
for _, node := range state.Masters {
9981045
s := node.Client.connPool.Stats()
9991046
acc.Hits += s.Hits
10001047
acc.Misses += s.Misses
@@ -1005,7 +1052,7 @@ func (c *ClusterClient) PoolStats() *PoolStats {
10051052
acc.StaleConns += s.StaleConns
10061053
}
10071054

1008-
for _, node := range state.slaves {
1055+
for _, node := range state.Slaves {
10091056
s := node.Client.connPool.Stats()
10101057
acc.Hits += s.Hits
10111058
acc.Misses += s.Misses
@@ -1438,7 +1485,7 @@ func isLoopbackAddr(addr string) bool {
14381485
return ip.IsLoopback()
14391486
}
14401487

1441-
func appendNode(nodes []*clusterNode, node *clusterNode) []*clusterNode {
1488+
func appendUniqueNode(nodes []*clusterNode, node *clusterNode) []*clusterNode {
14421489
for _, n := range nodes {
14431490
if n == node {
14441491
return nodes

0 commit comments

Comments
 (0)