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

Code before:
         * with the max number of non-failing replicas, consider migrating to
         * the orphaned primaries. Note that it does not make sense to try
         * a migration if there is no primary with at least *two* working
         * replicas. */
        if (orphaned_primaries && max_replicas >= 2 && this_replicas == max_replicas &&
            server.cluster_allow_replica_migration)
            clusterHandleReplicaMigration(max_replicas);
    }

    if (update_state || server.cluster->state == CLUSTER_FAIL) clusterUpdateState();
}

/* This function is called before the event handler returns to sleep for
 * events. It is useful to perform operations that must be done ASAP in
 * reaction to events fired but that are not safe to perform inside event
 * handlers, or to perform potentially expansive tasks that we need to do
 * a single time before replying to clients. */
void clusterBeforeSleep(void) {
    int flags = server.cluster->todo_before_sleep;

    /* Reset our flags (not strictly needed since every single function
     * called for flags set should be able to clear its flag). */
    server.cluster->todo_before_sleep = 0;

    /* Update the cluster state. We handle this flag first so that if we happen
     * to also has have failover flag, we can check the state first (and log the
     * state) before attempting the failover. */
    if (flags & CLUSTER_TODO_UPDATE_STATE) clusterUpdateState();

    if (flags & CLUSTER_TODO_HANDLE_MANUALFAILOVER) {
        /* Handle manual failover as soon as possible so that won't have a 100ms
         * as it was handled only in clusterCron */
        if (nodeIsReplica(myself)) {
            clusterHandleManualFailover();
            if (!(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) clusterHandleReplicaFailover();
        }
    } else if (flags & CLUSTER_TODO_HANDLE_FAILOVER) {
        /* Handle failover as soon as possible so that won't have a 100ms
         * as it was handled only in clusterCron. This is needed when it
         * is likely that we can start the election or there is already
         * the quorum from primaries in order to react fast. */
        if (nodeIsReplica(myself) &&
            !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) {
            clusterHandleReplicaFailover();
        }
    }

    /* Save the config, possibly using fsync. */
    if (flags & CLUSTER_TODO_SAVE_CONFIG) {
        int fsync = flags & CLUSTER_TODO_FSYNC_CONFIG;
        clusterSaveConfigOrDie(fsync);

Review comment (bug):
```suggestion
     * to also have a failover flag, we can check the state first (and log the
```

Code after:
         * with the max number of non-failing replicas, consider migrating to
         * the orphaned primaries. Note that it does not make sense to try
         * a migration if there is no primary with at least *two* working
         * replicas. */
        if (orphaned_primaries && max_replicas >= 2 && this_replicas == max_replicas &&
            server.cluster_allow_replica_migration)
            clusterHandleReplicaMigration(max_replicas);
    }

    if (update_state || server.cluster->state == CLUSTER_FAIL) clusterUpdateState();
}

/* This function is called before the event handler returns to sleep for
 * events. It is useful to perform operations that must be done ASAP in
 * reaction to events fired but that are not safe to perform inside event
 * handlers, or to perform potentially expansive tasks that we need to do
 * a single time before replying to clients. */
void clusterBeforeSleep(void) {
    int flags = server.cluster->todo_before_sleep;

    /* Reset our flags (not strictly needed since every single function
     * called for flags set should be able to clear its flag). */
    server.cluster->todo_before_sleep = 0;

    /* Update the cluster state. We handle this flag first so that if we happen
     * to also have a failover flag, we can check the state first (and log the
     * state) before attempting the failover. */
    if (flags & CLUSTER_TODO_UPDATE_STATE) clusterUpdateState();

    if (flags & CLUSTER_TODO_HANDLE_MANUALFAILOVER) {
        /* Handle manual failover as soon as possible so that won't have a 100ms
         * as it was handled only in clusterCron */
        if (nodeIsReplica(myself)) {
            clusterHandleManualFailover();
            if (!(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) clusterHandleReplicaFailover();
        }
    } else if (flags & CLUSTER_TODO_HANDLE_FAILOVER) {
        /* Handle failover as soon as possible so that won't have a 100ms
         * as it was handled only in clusterCron. This is needed when it
         * is likely that we can start the election or there is already
         * the quorum from primaries in order to react fast. */
        if (nodeIsReplica(myself) &&
            !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) {
            clusterHandleReplicaFailover();
        }
    }

    /* Save the config, possibly using fsync. */
    if (flags & CLUSTER_TODO_SAVE_CONFIG) {
        int fsync = flags & CLUSTER_TODO_FSYNC_CONFIG;
        clusterSaveConfigOrDie(fsync);