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

Code before:
     *
     * To mitigate this issue, the following order needs to be enforced for slot
     * migration finalization such that the replicas finalize the slot ownership
     * before the primary:
     *
     * 1. Client C issues SETSLOT n NODE B against node B.
     * 2. Primary B replicates `SETSLOT n NODE B` to all of its replicas (e.g., B', B'').
     * 3. Upon replication completion, primary B executes `SETSLOT n NODE B` and
     *    returns success to client C.
     * 4. The following steps can happen in parallel:
     *   a. Client C issues `SETSLOT n NODE B` against primary A.
     *   b. Primary B gossips its new slot ownership to the cluster (including A, A', etc.).
     *
     * This ensures that all replicas have the latest topology information, enabling
     * a reliable slot ownership transfer even if the primary node went down during
     * the process. */
    if (nodeIsPrimary(myself) && myself->num_replicas != 0 && !c->flag.replication_done) {
        /* Iterate through the list of replicas to check if there are any running
         * version 7.2 or older. Replicas running on these versions do
         * not support the CLUSTER SETSLOT command on replicas. If such a replica
         * is found, we should skip the replication and fall back to the old
         * non-replicated behavior.*/
        listIter li;
        listNode *ln;
        int legacy_replica_found = 0;
        int online_replica_found = 0;
        listRewind(server.replicas, &li);
        while ((ln = listNext(&li))) {
            client *r = ln->value;
            if (r->replica_version < 0x702ff /* 7.2.255 */) {
                legacy_replica_found++;
            }
            if (r->repl_state == REPLICA_STATE_ONLINE) {
                online_replica_found++;
            }
        }

        if (!legacy_replica_found && online_replica_found) {
            forceCommandPropagation(c, PROPAGATE_REPL);
            /* We are a primary and this is the first time we see this `SETSLOT`
             * command. Force-replicate the command to all of our replicas
             * first and only on success we will handle the command.
             * Note that
             * 1. All replicas are expected to ack the replication within the given timeout
             * 2. The repl offset target is set to the primary's current repl offset + 1.
             *    There is no concern of partial replication because replicas always
             *    ack the repl offset at the command boundary. */
            blockClientForReplicaAck(c, timeout_ms, server.primary_repl_offset + 1, online_replica_found, 0);
            /* Mark client as pending command for execution after replication to replicas. */
            c->flag.pending_command = 1;
            replicationRequestAckFromReplicas();

Review comment (suggestion):
```suggestion
        int num_eligible_replicas = 0;
```

Code after:
     *
     * To mitigate this issue, the following order needs to be enforced for slot
     * migration finalization such that the replicas finalize the slot ownership
     * before the primary:
     *
     * 1. Client C issues SETSLOT n NODE B against node B.
     * 2. Primary B replicates `SETSLOT n NODE B` to all of its replicas (e.g., B', B'').
     * 3. Upon replication completion, primary B executes `SETSLOT n NODE B` and
     *    returns success to client C.
     * 4. The following steps can happen in parallel:
     *   a. Client C issues `SETSLOT n NODE B` against primary A.
     *   b. Primary B gossips its new slot ownership to the cluster (including A, A', etc.).
     *
     * This ensures that all replicas have the latest topology information, enabling
     * a reliable slot ownership transfer even if the primary node went down during
     * the process. */
    if (nodeIsPrimary(myself) && myself->num_replicas != 0 && !c->flag.replication_done) {
        /* Iterate through the list of replicas to check if there are any running
         * version 7.2 or older. Replicas running on these versions do
         * not support the CLUSTER SETSLOT command on replicas. If such a replica
         * is found, we should skip the replication and fall back to the old
         * non-replicated behavior.*/
        listIter li;
        listNode *ln;
        int num_eligible_replicas = 0;
        listRewind(server.replicas, &li);
        while ((ln = listNext(&li))) {
            client *r = ln->value;

            /* We think that when the command comes in, the primary only needs to
             * wait for the online replicas. The admin can easily check if there
             * are replicas that are down for an extended period of time. If they
             * decide to move forward anyways, we should not block it. If a replica
             * failed right before the replication and was not included in the
             * replication, it would also unlikely win the election.
             *
             * And 0x702ff is 7.2.255, we only support new versions in this case. */
            if (r->repl_state == REPLICA_STATE_ONLINE && r->replica_version > 0x702ff) {
                num_eligible_replicas++;
            }
        }

        if (num_eligible_replicas != 0) {
            forceCommandPropagation(c, PROPAGATE_REPL);
            /* We are a primary and this is the first time we see this `SETSLOT`
             * command. Force-replicate the command to all of our replicas
             * first and only on success will we handle the command.
             * Note that
             * 1. All replicas are expected to ack the replication within the given timeout
             * 2. The repl offset target is set to the primary's current repl offset + 1.
             *    There is no concern of partial replication because replicas always