@@ -683,7 +683,7 @@ static int cluster_map_slots(redisCluster *c, clusterReply *r) {
683683 clusterReply * r2 , * r3 ;
684684 unsigned short port ;
685685 char * host , key [1024 ];
686-
686+ zend_hash_clean ( c -> nodes );
687687 for (i = 0 ; i < r -> elements ; i ++ ) {
688688 // Inner response
689689 r2 = r -> element [i ];
@@ -1396,7 +1396,7 @@ static void cluster_update_slot(redisCluster *c) {
13961396 /* Do we already have the new slot mapped */
13971397 if (c -> master [c -> redir_slot ]) {
13981398 /* 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 ) )) {
14001400 return ;
14011401 }
14021402
@@ -1407,6 +1407,22 @@ static void cluster_update_slot(redisCluster *c) {
14071407 /* Just point to this slot */
14081408 c -> master [c -> redir_slot ] = node ;
14091409 } 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+
14101426 /* Create our node */
14111427 node = cluster_node_create (c , c -> redir_host , c -> redir_host_len ,
14121428 c -> redir_port , c -> redir_slot , 0 );
0 commit comments