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

Code before:
     * This check is done early to preserve historical behavior. */
    if (n == NULL) {
        if (error_code) *error_code = CLUSTER_REDIR_DOWN_UNBOUND;
        return NULL;
    }

    /* If we are migrating or importing this slot, we need to check
     * if we have all the keys in the request (the only way we
     * can safely serve the request, otherwise we return a TRYAGAIN
     * error). To do so we set the importing/migrating state and
     * increment a counter for every missing key. */
    if (clusterNodeIsPrimary(myself) || c->flag.readonly) {
        if (n == clusterNodeGetPrimary(myself) && getMigratingSlotDest(c->slot) != NULL) {
            migrating_slot = 1;
        } else if (getImportingSlotSource(c->slot) != NULL) {
            importing_slot = 1;
        }
    }

    uint64_t cmd_flags = getCommandFlags(c);

    /* Only valid for sharded pubsub as regular pubsub can operate on any node and bypasses this layer. */
    int pubsubshard_included =
        (cmd_flags & CMD_PUBSUB) || (c->cmd->proc == execCommand && (c->mstate->cmd_flags & CMD_PUBSUB));

    /* If we're importing or migration the slot, we need to do some more checks:
     *
     *   1. Go over all the keys to count existing keys and missing keys that we
     *      need for TRYAGAIN and ASK redirects.
     *   2. Check for some commands that are forbiddedn during slot migration.
     *
     * Skip this if we're not importing or migrating this slot. */
    if (!migrating_slot && !importing_slot) goto after_checking_each_key;

    /* We handle all the cases as if they were EXEC commands, so we have
     * a common code path for everything */
    if (c->cmd->proc == execCommand) {
        /* If CLIENT_MULTI flag is not set EXEC is just going to return an
         * error. */
        if (!c->flag.multi) return myself;
        ms = c->mstate;
    } else {
        /* In order to have a single codepath create a fake Multi State
         * structure if the client is not in MULTI/EXEC state, this way
         * we have a single codepath below. */
        ms = &_ms;
        _ms.commands = &mc;
        _ms.count = 1;
        mc.argv = c->argv;
        mc.argc = c->argc;
        mc.cmd = c->cmd;

Review comment (suggestion):
```suggestion
    /* If we're importing or migrating the slot, we need to do some more checks:
```

Code after:
     * This check is done early to preserve historical behavior. */
    if (n == NULL) {
        if (error_code) *error_code = CLUSTER_REDIR_DOWN_UNBOUND;
        return NULL;
    }

    /* If we are migrating or importing this slot, we need to check
     * if we have all the keys in the request (the only way we
     * can safely serve the request, otherwise we return a TRYAGAIN
     * error). To do so we set the importing/migrating state and
     * increment a counter for every missing key. */
    if (clusterNodeIsPrimary(myself) || c->flag.readonly) {
        if (n == clusterNodeGetPrimary(myself) && getMigratingSlotDest(c->slot) != NULL) {
            migrating_slot = 1;
        } else if (getImportingSlotSource(c->slot) != NULL) {
            importing_slot = 1;
        }
    }

    uint64_t cmd_flags = getCommandFlags(c);

    /* Only valid for sharded pubsub as regular pubsub can operate on any node and bypasses this layer. */
    int pubsubshard_included =
        (cmd_flags & CMD_PUBSUB) || (c->cmd->proc == execCommand && (c->mstate->cmd_flags & CMD_PUBSUB));

    /* If we're importing or migrating the slot, we need to do some more checks:
     *
     *   1. Go over all the keys to count existing keys and missing keys that we
     *      need for TRYAGAIN and ASK redirects.
     *   2. Check for some commands that are forbiddedn during slot migration.
     *
     * Skip this if we're not importing or migrating this slot. */
    if (!migrating_slot && !importing_slot) goto after_checking_each_key;

    /* We handle all the cases as if they were EXEC commands, so we have
     * a common code path for everything */
    if (c->cmd->proc == execCommand) {
        /* If CLIENT_MULTI flag is not set EXEC is just going to return an
         * error. */
        if (!c->flag.multi) return myself;
        ms = c->mstate;
    } else {
        /* In order to have a single codepath create a fake Multi State
         * structure if the client is not in MULTI/EXEC state, this way
         * we have a single codepath below. */
        ms = &_ms;
        _ms.commands = &mc;
        _ms.count = 1;
        mc.argv = c->argv;
        mc.argc = c->argc;
        mc.cmd = c->cmd;