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

Code before:
    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));

    serverDb *currentDb = c->db;

    /* Check that all the keys are in the same hash slot, and obtain this
     * slot and the node associated. */
    for (i = 0; i < ms->count; i++) {
        struct serverCommand *mcmd;
        robj **margv;
        int margc, numkeys, j;
        keyReference *keyindex;

        mcmd = ms->commands[i].cmd;
        margc = ms->commands[i].argc;
        margv = ms->commands[i].argv;

        getKeysResult result;
        initGetKeysResult(&result);
        numkeys = getKeysFromCommand(mcmd, margv, margc, &result);
        keyindex = result.keys;

        if (mcmd->proc == selectCommand) {
            /* Failed SELECT is ignored since it doesn't modify the database. */
            serverDb *origDb = currentDb;
            long long id;
            if (getLongLongFromObject(margv[1], &id) == C_OK && selectDb(c, id) == C_OK) {
                currentDb = c->db;
                selectDb(c, origDb->id);
            }
        }

        for (j = 0; j < numkeys; j++) {
            robj *thiskey = margv[keyindex[j].pos];
            int thisslot = keyHashSlot((char *)thiskey->ptr, sdslen(thiskey->ptr));

            if (firstkey == NULL) {
                /* This is the first key we see. Check what is the slot
                 * and node. */
                firstkey = thiskey;
                slot = thisslot;
                n = getNodeBySlot(slot);

                /* Error: If a slot is not served, we are in "cluster down"
                 * state. However the state is yet to be updated, so this was
                 * not trapped earlier in processCommand(). Report the same
                 * error to the client. */
                if (n == NULL) {

Review comment (suggestion):
maybe introduce a new `mc_slot` field in `client` and keep it updated after parsing every child command. this way we can avoid this loop, making the code easier to read and also less code to execute. 

Code after:
 * down but the user attempts to execute a command that addresses one or more keys. */
clusterNode *getNodeByQuery(client *c, int *error_code) {
    clusterNode *myself = getMyClusterNode();
    clusterNode *n = NULL;
    robj *firstkey = NULL;
    int multiple_keys = 0;
    multiState *ms, _ms;
    multiCmd mc;
    int i, migrating_slot = 0, importing_slot = 0, missing_keys = 0, existing_keys = 0;

    /* Slot must be calculated in advance, or cross-slot or no keys detected. */
    serverAssert(c->slot >= 0 || c->read_flags & (READ_FLAGS_NO_KEYS | READ_FLAGS_CROSSSLOT));

    /* Allow any key to be set if a module disabled cluster redirections. */
    if (server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_REDIRECTION) return myself;

    /* Set error code optimistically for the base case. */
    if (error_code) *error_code = CLUSTER_REDIR_NONE;

    /* Modules can turn off Cluster redirection: this is useful
     * when writing a module that implements a completely different
     * distributed system. */

    /* Determine transaction slot and return early on cross-slot. */
    if (c->cmd->proc == execCommand && c->flag.multi) {
        int slot = -1;
        for (i = 0; i < c->mstate->count; i++) {
            if (slot == -1) {
                slot = c->mstate->commands[i].slot;
            } else if (c->mstate->commands[i].slot != -1 && c->mstate->commands[i].slot != slot) {
                if (error_code) *error_code = CLUSTER_REDIR_CROSS_SLOT;
                return NULL;
            }
        }
        /* EXEC will execute all queued commands in the transaction, so we
         * overwrite the EXEC commands's slot with the transaction's slot. */
        c->slot = slot;
    } else if (c->read_flags & READ_FLAGS_CROSSSLOT) {
        if (error_code) *error_code = CLUSTER_REDIR_CROSS_SLOT;
        return NULL;
    }

    /* No key at all in command? then we can serve the request
     * without redirections or errors in all the cases. */
    if (c->slot == -1) return myself;

    n = getNodeBySlot(c->slot);

    /* If a slot is not served, we are in "cluster down" state.
     * This check is done early to preserve historical behavior. */
    if (n == NULL) {