Sitelet https://github.com/phpredis/phpredis/pull/2025/files
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions cluster_library.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ static int cluster_map_slots(redisCluster *c, clusterReply *r) {
clusterReply *r2, *r3;
unsigned short port;
char *host, key[1024];

zend_hash_clean(c->nodes);
for (i = 0; i < r->elements; i++) {
// Inner response
r2 = r->element[i];
Expand Down Expand Up @@ -1396,7 +1396,7 @@ static void cluster_update_slot(redisCluster *c) {
/* Do we already have the new slot mapped */
if (c->master[c->redir_slot]) {
/* No need to do anything if it's the same node */
if (!CLUSTER_REDIR_CMP(c)) {
if (!CLUSTER_REDIR_CMP(c, SLOT_SOCK(c,c->redir_slot))) {
return;
}

Expand All @@ -1407,6 +1407,22 @@ static void cluster_update_slot(redisCluster *c) {
/* Just point to this slot */
c->master[c->redir_slot] = node;
} else {
/* If the redirected node is a replica of the previous slot owner, a failover has taken place.
We must then remap the cluster's keyspace in order to update the cluster's topology. */
redisClusterNode *prev_master = SLOT(c,c->redir_slot);
redisClusterNode *slave;
ZEND_HASH_FOREACH_PTR(prev_master->slaves, slave) {
if (slave == NULL) {
continue;
}
if (!CLUSTER_REDIR_CMP(c, slave->sock)) {
// Detected a failover, the redirected node was a replica
// Remap the cluster's keyspace
cluster_map_keyspace(c);
return;
}
} ZEND_HASH_FOREACH_END();

/* Create our node */
node = cluster_node_create(c, c->redir_host, c->redir_host_len,
c->redir_port, c->redir_slot, 0);
Expand Down
10 changes: 5 additions & 5 deletions cluster_library.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@
#define CMD_SOCK(c) (c->cmd_sock)
#define CMD_STREAM(c) (c->cmd_sock->stream)

/* Compare redirection slot information with what we have */
#define CLUSTER_REDIR_CMP(c) \
(SLOT_SOCK(c,c->redir_slot)->port != c->redir_port || \
ZSTR_LEN(SLOT_SOCK(c,c->redir_slot)->host) != c->redir_host_len || \
memcmp(ZSTR_VAL(SLOT_SOCK(c,c->redir_slot)->host),c->redir_host,c->redir_host_len))
/* Compare redirection slot information with the passed node */
#define CLUSTER_REDIR_CMP(c, sock) \
(sock->port != c->redir_port || \
ZSTR_LEN(sock->host) != c->redir_host_len || \
memcmp(ZSTR_VAL(sock->host),c->redir_host,c->redir_host_len))

/* Clear out our "last error" */
#define CLUSTER_CLEAR_ERROR(c) do { \
Expand Down