Repository: valkey-io/valkey
File: src/cluster_legacy.c (C)

Code before:
        exit(1);
    }

    if (createSocketAcceptHandler(&server.clistener, clusterAcceptHandler) != C_OK) {
        serverPanic("Unrecoverable error creating Cluster socket accept handler.");
    }
}

void clusterAutoFailoverOnShutdown(void) {
    if (!nodeIsPrimary(myself) || !server.auto_failover_on_shutdown) return;

    /* Find the first best replica, that is, the replica with the largest offset. */
    int legacy_replica = 0;
    client *best_replica = NULL;
    listIter replicas_iter;
    listNode *replicas_list_node;
    listRewind(server.replicas, &replicas_iter);
    while ((replicas_list_node = listNext(&replicas_iter)) != NULL) {
        client *replica = listNodeValue(replicas_list_node);
        /* This is done only when the replica offset is caught up, to avoid data loss.
         * And 0x80100 is 8.1.0, we only support this feature in this version. */
        if (replica->repl_data->replica_version < 0x80100) {
            legacy_replica = 1;
            best_replica = NULL;
            break;
        }
        if (replica->repl_data->repl_state == REPLICA_STATE_ONLINE &&
            replica->repl_data->repl_ack_off == server.primary_repl_offset &&
            replica->repl_data->replica_nodeid && sdslen(replica->repl_data->replica_nodeid) == CLUSTER_NAMELEN) {
            best_replica = replica;
        }
    }

    /* We are not able to find the replica to do the auto failover. */
    if (best_replica == NULL) {
        if (legacy_replica) {
            serverLog(LL_NOTICE, "Unable to perform auto failover on shutdown since there are legacy replicas.");
        } else {
            serverLog(LL_NOTICE, "Unable to find a replica to perform the auto failover on shutdown.");
        }
        return;
    }

    /* Send the CLUSTER FAILOVER FORCE REPLICAID node-id to all replicas since
     * it is a shared replication buffer, but only the replica with the matching
     * node-id will execute it. The caller will call flushReplicasOutputBuffers,
     * so in here it is a best effort. */
    char buf[128];
    size_t buflen = snprintf(buf, sizeof(buf),
                             "*5\r\n$7\r\nCLUSTER\r\n"
                             "$8\r\nFAILOVER\r\n"

Review comment (suggestion):
Shouldn't we loop over all the replicas and make the decision ?

```suggestion
        if (replica->repl_data->replica_version < 0x80100) {
            legacy_replica = 1;
            continue;
        }
```

best_replica is already NULL. So, we can remove that statement as well.

Code after:
    listener->ct = connTypeOfCluster();
    if (connListen(listener) == C_ERR) {
        /* Note: the following log text is matched by the test suite. */
        serverLog(LL_WARNING, "Failed listening on port %u (cluster), aborting.", listener->port);
        exit(1);
    }

    if (createSocketAcceptHandler(&server.clistener, clusterAcceptHandler) != C_OK) {
        serverPanic("Unrecoverable error creating Cluster socket accept handler.");
    }
}

void clusterAutoFailoverOnShutdown(void) {
    if (!nodeIsPrimary(myself) || !server.auto_failover_on_shutdown) return;

    /* Find the first best replica, that is, the replica with the largest offset. */
    int legacy_replica = 0;
    client *best_replica = NULL;
    listIter replicas_iter;
    listNode *replicas_list_node;
    listRewind(server.replicas, &replicas_iter);
    while ((replicas_list_node = listNext(&replicas_iter)) != NULL) {
        client *replica = listNodeValue(replicas_list_node);
        /* This is done only when the replica offset is caught up, to avoid data loss.
         * And 0x90000 is 9.0.0, we only support this feature in this version. */
        if (replica->repl_data->replica_version < 0x90000) {
            legacy_replica = 1;
            best_replica = NULL;
            break;
        }
        if (replica->repl_data->repl_state == REPLICA_STATE_ONLINE &&
            replica->repl_data->repl_ack_off == server.primary_repl_offset &&
            replica->repl_data->replica_nodeid && sdslen(replica->repl_data->replica_nodeid) == CLUSTER_NAMELEN) {
            best_replica = replica;
        }
    }

    /* We are not able to find the replica to do the auto failover. */
    if (best_replica == NULL) {
        if (legacy_replica) {
            serverLog(LL_NOTICE, "Unable to perform auto failover on shutdown since there are legacy replicas.");
        } else {
            serverLog(LL_NOTICE, "Unable to find a replica to perform the auto failover on shutdown.");
        }
        return;
    }

    /* Send the CLUSTER FAILOVER FORCE REPLICAID node-id to all replicas since
     * it is a shared replication buffer, but only the replica with the matching
     * node-id will execute it. The caller will call flushReplicasOutputBuffers,
     * so in here it is a best effort. */