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

Code before:

/* 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. */
        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 0x800ff is 8.0.255, we only support new versions for this feature. */
            if (replica->repl_data->repl_state == REPLICA_STATE_ONLINE &&
                // replica->repl_data->replica_version > 0x800ff &&
                replica->name && sdslen(replica->name->ptr) == CLUSTER_NAMELEN &&
                replica->repl_data->repl_ack_off == server.primary_repl_offset) {
                best_replica = replica;
                break;
            }
        }

        if (best_replica) {
            /* Send a CLUSTER FAILOVER FORCE to the best replica. */
            char buf[128];
            size_t buflen = snprintf(buf, sizeof(buf), "*5\r\n$7\r\nCLUSTER\r\n$8\r\nFAILOVER\r\n$5\r\nFORCE\r\n$9\r\nreplicaid\r\n$%d\r\n%s\r\n", CLUSTER_NAMELEN, (char *)best_replica->name->ptr);
            if (connWrite(best_replica->conn, buf, buflen) == (int)strlen(buf)) {
                serverLog(LL_NOTICE, "Sending CLUSTER FAILOVER FORCE to replica %s succeeded.",
                          replicationGetReplicaName(best_replica));
            } else {
                serverLog(LL_WARNING, "Failed to send CLUSTER FAILOVER FORCE to replica: %s", strerror(errno));
            }
        } else {
            serverLog(LL_NOTICE, "Unable to find a replica to perform an auto failover on shutdown.");
        }
    }

    /* The error logs have been logged in the save function if the save fails. */
    serverLog(LL_NOTICE, "Saving the cluster configuration file before exiting.");
    clusterSaveConfig(1);

#if !defined(__sun)
    /* Unlock the cluster config file before shutdown, see clusterLockConfig.
     *
     * This is needed if you shutdown a very large server process, it will take
     * a while for the OS to release resources and unlock the cluster configuration
     * file. Therefore, if we immediately try to restart the server process, it
     * may not be able to acquire the lock on the cluster configuration file and
     * fail to start. We explicitly releases the lock on the cluster configuration
     * file on shutdown, rather than relying on the OS to release the lock, which
     * is a cleaner and safer way to release acquired resources. */

Review comment (bug):
Very long line. Maybe break it?

Why is "replicaid" in lowercase? Other keywords are uppercase, like "FORCE".

```suggestion
            size_t buflen = snprintf(buf, sizeof(buf),
                                     "*5\r\n$7\r\nCLUSTER\r\n"
                                     "$8\r\nFAILOVER\r\n"
                                     "$5\r\nFORCE\r\n"
                                     "$9\r\nREPLICAID\r\n"
                                     "$%d\r\n%s\r\n",
                                     CLUSTER_NAMELEN,
                                     (char *)best_replica->name->ptr);
```

Code after:
    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. */
    if (best_replica == NULL) {