Call() is the core of Redis execution of a command. * * The following flags can be passed: * CMD_CALL_NONE No flags. * CMD_CALL_SLOWLOG Check command speed and log in the slow log if needed. * CMD_CALL_STATS Populate command stats. * CMD_CALL_PROPAGATE_AOF Append command to AOF if it modified the dataset * or if the client flags are forcing propag
| 3702 | * |
| 3703 | */ |
| 3704 | void call(client *c, int flags) { |
| 3705 | long long dirty; |
| 3706 | monotime call_timer; |
| 3707 | int client_old_flags = c->flags; |
| 3708 | struct redisCommand *real_cmd = c->cmd; |
| 3709 | static long long prev_err_count; |
| 3710 | |
| 3711 | /* Initialization: clear the flags that must be set by the command on |
| 3712 | * demand, and initialize the array for additional commands propagation. */ |
| 3713 | c->flags &= ~(CLIENT_FORCE_AOF|CLIENT_FORCE_REPL|CLIENT_PREVENT_PROP); |
| 3714 | redisOpArray prev_also_propagate = server.also_propagate; |
| 3715 | redisOpArrayInit(&server.also_propagate); |
| 3716 | |
| 3717 | /* Call the command. */ |
| 3718 | dirty = server.dirty; |
| 3719 | prev_err_count = server.stat_total_error_replies; |
| 3720 | |
| 3721 | /* Update cache time, in case we have nested calls we want to |
| 3722 | * update only on the first call*/ |
| 3723 | if (server.fixed_time_expire++ == 0) { |
| 3724 | updateCachedTime(0); |
| 3725 | } |
| 3726 | |
| 3727 | elapsedStart(&call_timer); |
| 3728 | c->cmd->proc(c); |
| 3729 | const long duration = elapsedUs(call_timer); |
| 3730 | c->duration = duration; |
| 3731 | dirty = server.dirty-dirty; |
| 3732 | if (dirty < 0) dirty = 0; |
| 3733 | |
| 3734 | /* Update failed command calls if required. |
| 3735 | * We leverage a static variable (prev_err_count) to retain |
| 3736 | * the counter across nested function calls and avoid logging |
| 3737 | * the same error twice. */ |
| 3738 | if ((server.stat_total_error_replies - prev_err_count) > 0) { |
| 3739 | real_cmd->failed_calls++; |
| 3740 | } |
| 3741 | |
| 3742 | /* After executing command, we will close the client after writing entire |
| 3743 | * reply if it is set 'CLIENT_CLOSE_AFTER_COMMAND' flag. */ |
| 3744 | if (c->flags & CLIENT_CLOSE_AFTER_COMMAND) { |
| 3745 | c->flags &= ~CLIENT_CLOSE_AFTER_COMMAND; |
| 3746 | c->flags |= CLIENT_CLOSE_AFTER_REPLY; |
| 3747 | } |
| 3748 | |
| 3749 | /* When EVAL is called loading the AOF we don't want commands called |
| 3750 | * from Lua to go into the slowlog or to populate statistics. */ |
| 3751 | if (server.loading && c->flags & CLIENT_LUA) |
| 3752 | flags &= ~(CMD_CALL_SLOWLOG | CMD_CALL_STATS); |
| 3753 | |
| 3754 | /* If the caller is Lua, we want to force the EVAL caller to propagate |
| 3755 | * the script if the command flag or client flag are forcing the |
| 3756 | * propagation. */ |
| 3757 | if (c->flags & CLIENT_LUA && server.lua_caller) { |
| 3758 | if (c->flags & CLIENT_FORCE_REPL) |
| 3759 | server.lua_caller->flags |= CLIENT_FORCE_REPL; |
| 3760 | if (c->flags & CLIENT_FORCE_AOF) |
| 3761 | server.lua_caller->flags |= CLIENT_FORCE_AOF; |
no test coverage detected