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

Code before:
        exit(1);
    }

    int port = defaultClientPort();
    connListener *listener = &server.clistener;
    listener->count = 0;
    listener->bindaddr = server.bindaddr;
    listener->bindaddr_count = server.bindaddr_count;
    listener->port = server.cluster_port ? server.cluster_port : port + CLUSTER_PORT_INCR;
    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.");
    }
}

/* Called when a cluster node receives SHUTDOWN. */
void clusterHandleServerShutdown(void) {
    if (nodeIsPrimary(myself) && server.auto_failover_on_shutdown) {
        /* Find the first best replica, that is, the replica with the largest offset. */
        int old_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) {
                old_replica = 1;
                best_replica = NULL;
                break;
            }
            if (replica->repl_data->repl_state == REPLICA_STATE_ONLINE &&
                replica->name && sdslen(replica->name->ptr) == CLUSTER_NAMELEN &&
                replica->repl_data->repl_ack_off == server.primary_repl_offset) {
                best_replica = replica;
            }
        }

        if (best_replica) {
            /* 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. */

Review comment (suggestion):
nit. legacy? "old" struck me as being an "out of sync" replica at first.

```suggestion
        int legacy_replica = 0;
```

Code after:
void clusterInitLast(void) {
    if (connectionIndexByType(connTypeOfCluster()->get_type(NULL)) < 0) {
        serverLog(LL_WARNING, "Missing connection type %s, but it is required for the Cluster bus.",
                  connTypeOfCluster()->get_type(NULL));
        exit(1);
    }

    int port = defaultClientPort();
    connListener *listener = &server.clistener;
    listener->count = 0;
    listener->bindaddr = server.bindaddr;
    listener->bindaddr_count = server.bindaddr_count;
    listener->port = server.cluster_port ? server.cluster_port : port + CLUSTER_PORT_INCR;
    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. */