Skip to content

(ClusterClient).ForEachNode does not cover all nodes #701

Closed
@gbbr

Description

@gbbr

In a cluster with 3 masters (ports 7000-7002) and 3 slaves (ports 7003-7005) connected as:

c := redis.NewClusterClient(&redis.ClusterOptions{
	Addrs: []string{":7000", ":7001", ":7002"},
})

Using WrapProcess inside ForEachNode does not wrap each client, leaving gaps. ForEachNode uses a for loop to go through each master (state.masters) and slave (state.slaves), but omits some nodes (state.nodes.nodes).

In the above setup, the state field contains:

state.masters:
172.17.0.2:7002
172.17.0.2:7000
172.17.0.2:7001

state.slaves:
172.17.0.2:7005
172.17.0.2:7003
172.17.0.2:7004

state.nodes.nodes:
172.17.0.2:7002
172.17.0.2:7005
172.17.0.2:7000
172.17.0.2:7003
172.17.0.2:7004
:7000
:7001
:7002
172.17.0.2:7001

Even though ForEachNode goes as expected through each unique node, it does not offer the possibility to tap into every client. One possible fix could be:

diff --git a/cluster.go b/cluster.go
index a2c18b3..8761000 100644
--- a/cluster.go
+++ b/cluster.go
@@ -816,11 +816,7 @@ func (c *ClusterClient) ForEachNode(fn func(client *Client) error) error {
 		}
 	}
 
-	for _, node := range state.masters {
-		wg.Add(1)
-		go worker(node)
-	}
-	for _, node := range state.slaves {
+	for _, node := range state.nodes.nodes {
 		wg.Add(1)
 		go worker(node)
 	}

Would this change or a similar one make sense? Or am I doing something stupid?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions