Now Lua scripts dispatch Redis commands properly calling the call() function. In order to make this possible call() was improved with a new flags argument that controls how the Redis command is executed.

This commit is contained in:
antirez 2012-02-02 16:30:52 +01:00
parent d876678b5e
commit ce8b772be7
4 changed files with 33 additions and 15 deletions

View File

@ -112,7 +112,7 @@ void execCommand(redisClient *c) {
c->argc = c->mstate.commands[j].argc; c->argc = c->mstate.commands[j].argc;
c->argv = c->mstate.commands[j].argv; c->argv = c->mstate.commands[j].argv;
c->cmd = c->mstate.commands[j].cmd; c->cmd = c->mstate.commands[j].cmd;
call(c); call(c,REDIS_CALL_FULL);
/* Commands may alter argc/argv, restore mstate. */ /* Commands may alter argc/argv, restore mstate. */
c->mstate.commands[j].argc = c->argc; c->mstate.commands[j].argc = c->argc;

View File

@ -1171,17 +1171,26 @@ struct redisCommand *lookupCommandByCString(char *s) {
} }
/* Call() is the core of Redis execution of a command */ /* Call() is the core of Redis execution of a command */
void call(redisClient *c) { void call(redisClient *c, int flags) {
long long dirty, start = ustime(), duration; long long dirty, start = ustime(), duration;
dirty = server.dirty; dirty = server.dirty;
c->cmd->proc(c); c->cmd->proc(c);
dirty = server.dirty-dirty; dirty = server.dirty-dirty;
duration = ustime()-start; duration = ustime()-start;
c->cmd->microseconds += duration;
slowlogPushEntryIfNeeded(c->argv,c->argc,duration);
c->cmd->calls++;
/* When EVAL is called loading the AOF we don't want commands called
* from Lua to go into the slowlog or to populate statistics. */
if (server.loading && c->flags & REDIS_LUA_CLIENT)
flags &= ~(REDIS_CALL_SLOWLOG | REDIS_CALL_STATS);
if (flags & REDIS_CALL_SLOWLOG)
slowlogPushEntryIfNeeded(c->argv,c->argc,duration);
if (flags & REDIS_CALL_STATS) {
c->cmd->microseconds += duration;
c->cmd->calls++;
}
if (flags & REDIS_CALL_PROPAGATE) {
if (server.aof_state != REDIS_AOF_OFF && dirty > 0) if (server.aof_state != REDIS_AOF_OFF && dirty > 0)
feedAppendOnlyFile(c->cmd,c->db->id,c->argv,c->argc); feedAppendOnlyFile(c->cmd,c->db->id,c->argv,c->argc);
if ((dirty > 0 || c->cmd->flags & REDIS_CMD_FORCE_REPLICATION) && if ((dirty > 0 || c->cmd->flags & REDIS_CMD_FORCE_REPLICATION) &&
@ -1189,6 +1198,7 @@ void call(redisClient *c) {
replicationFeedSlaves(server.slaves,c->db->id,c->argv,c->argc); replicationFeedSlaves(server.slaves,c->db->id,c->argv,c->argc);
if (listLength(server.monitors)) if (listLength(server.monitors))
replicationFeedMonitors(server.monitors,c->db->id,c->argv,c->argc); replicationFeedMonitors(server.monitors,c->db->id,c->argv,c->argc);
}
server.stat_numcommands++; server.stat_numcommands++;
} }
@ -1317,7 +1327,7 @@ int processCommand(redisClient *c) {
queueMultiCommand(c); queueMultiCommand(c);
addReply(c,shared.queued); addReply(c,shared.queued);
} else { } else {
call(c); call(c,REDIS_CALL_FULL);
} }
return REDIS_OK; return REDIS_OK;
} }

View File

@ -237,6 +237,13 @@
points are configured. */ points are configured. */
#define REDIS_SHUTDOWN_NOSAVE 2 /* Don't SAVE on SHUTDOWN. */ #define REDIS_SHUTDOWN_NOSAVE 2 /* Don't SAVE on SHUTDOWN. */
/* Command call flags, see call() function */
#define REDIS_CALL_NONE 0
#define REDIS_CALL_SLOWLOG 1
#define REDIS_CALL_STATS 2
#define REDIS_CALL_PROPAGATE 4
#define REDIS_CALL_FULL (REDIS_CALL_SLOWLOG | REDIS_CALL_STATS | REDIS_CALL_PROPAGATE)
/* We can print the stacktrace, so our assert is defined this way: */ /* We can print the stacktrace, so our assert is defined this way: */
#define redisAssertWithInfo(_c,_o,_e) ((_e)?(void)0 : (_redisAssertWithInfo(_c,_o,#_e,__FILE__,__LINE__),_exit(1))) #define redisAssertWithInfo(_c,_o,_e) ((_e)?(void)0 : (_redisAssertWithInfo(_c,_o,#_e,__FILE__,__LINE__),_exit(1)))
#define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1))) #define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
@ -938,7 +945,7 @@ int processCommand(redisClient *c);
void setupSignalHandlers(void); void setupSignalHandlers(void);
struct redisCommand *lookupCommand(sds name); struct redisCommand *lookupCommand(sds name);
struct redisCommand *lookupCommandByCString(char *s); struct redisCommand *lookupCommandByCString(char *s);
void call(redisClient *c); void call(redisClient *c, int flags);
int prepareForShutdown(); int prepareForShutdown();
void redisLog(int level, const char *fmt, ...); void redisLog(int level, const char *fmt, ...);
void redisLogRaw(int level, const char *msg); void redisLogRaw(int level, const char *msg);

View File

@ -221,7 +221,8 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
if (cmd->flags & REDIS_CMD_WRITE) server.lua_write_dirty = 1; if (cmd->flags & REDIS_CMD_WRITE) server.lua_write_dirty = 1;
/* Run the command */ /* Run the command */
cmd->proc(c); c->cmd = cmd;
call(c,REDIS_CALL_SLOWLOG | REDIS_CALL_STATS);
/* Convert the result of the Redis command into a suitable Lua type. /* Convert the result of the Redis command into a suitable Lua type.
* The first thing we need is to create a single string from the client * The first thing we need is to create a single string from the client