@@ -683,7 +683,7 @@ static int cluster_map_slots(redisCluster *c, clusterReply *r) {
683
683
clusterReply * r2 , * r3 ;
684
684
unsigned short port ;
685
685
char * host , key [1024 ];
686
-
686
+ zend_hash_clean ( c -> nodes );
687
687
for (i = 0 ; i < r -> elements ; i ++ ) {
688
688
// Inner response
689
689
r2 = r -> element [i ];
@@ -1396,7 +1396,7 @@ static void cluster_update_slot(redisCluster *c) {
1396
1396
/* Do we already have the new slot mapped */
1397
1397
if (c -> master [c -> redir_slot ]) {
1398
1398
/* No need to do anything if it's the same node */
1399
- if (!CLUSTER_REDIR_CMP (c )) {
1399
+ if (!CLUSTER_REDIR_CMP (c , SLOT_SOCK ( c , c -> redir_slot ) )) {
1400
1400
return ;
1401
1401
}
1402
1402
@@ -1407,6 +1407,22 @@ static void cluster_update_slot(redisCluster *c) {
1407
1407
/* Just point to this slot */
1408
1408
c -> master [c -> redir_slot ] = node ;
1409
1409
} else {
1410
+ /* If the redirected node is a replica of the previous slot owner, a failover has taken place.
1411
+ We must then remap the cluster's keyspace in order to update the cluster's topology. */
1412
+ redisClusterNode * prev_master = SLOT (c ,c -> redir_slot );
1413
+ redisClusterNode * slave ;
1414
+ ZEND_HASH_FOREACH_PTR (prev_master -> slaves , slave ) {
1415
+ if (slave == NULL ) {
1416
+ continue ;
1417
+ }
1418
+ if (!CLUSTER_REDIR_CMP (c , slave -> sock )) {
1419
+ // Detected a failover, the redirected node was a replica
1420
+ // Remap the cluster's keyspace
1421
+ cluster_map_keyspace (c );
1422
+ return ;
1423
+ }
1424
+ } ZEND_HASH_FOREACH_END ();
1425
+
1410
1426
/* Create our node */
1411
1427
node = cluster_node_create (c , c -> redir_host , c -> redir_host_len ,
1412
1428
c -> redir_port , c -> redir_slot , 0 );
0 commit comments