Commit ce8b772b authored by antirez's avatar antirez
Browse files

Now Lua scripts dispatch Redis commands properly calling the call() function....

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.
parent d876678b
...@@ -112,7 +112,7 @@ void execCommand(redisClient *c) { ...@@ -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;
......
...@@ -1171,24 +1171,34 @@ struct redisCommand *lookupCommandByCString(char *s) { ...@@ -1171,24 +1171,34 @@ 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); /* When EVAL is called loading the AOF we don't want commands called
c->cmd->calls++; * from Lua to go into the slowlog or to populate statistics. */
if (server.loading && c->flags & REDIS_LUA_CLIENT)
if (server.aof_state != REDIS_AOF_OFF && dirty > 0) flags &= ~(REDIS_CALL_SLOWLOG | REDIS_CALL_STATS);
feedAppendOnlyFile(c->cmd,c->db->id,c->argv,c->argc);
if ((dirty > 0 || c->cmd->flags & REDIS_CMD_FORCE_REPLICATION) && if (flags & REDIS_CALL_SLOWLOG)
listLength(server.slaves)) slowlogPushEntryIfNeeded(c->argv,c->argc,duration);
replicationFeedSlaves(server.slaves,c->db->id,c->argv,c->argc); if (flags & REDIS_CALL_STATS) {
if (listLength(server.monitors)) c->cmd->microseconds += duration;
replicationFeedMonitors(server.monitors,c->db->id,c->argv,c->argc); c->cmd->calls++;
}
if (flags & REDIS_CALL_PROPAGATE) {
if (server.aof_state != REDIS_AOF_OFF && dirty > 0)
feedAppendOnlyFile(c->cmd,c->db->id,c->argv,c->argc);
if ((dirty > 0 || c->cmd->flags & REDIS_CMD_FORCE_REPLICATION) &&
listLength(server.slaves))
replicationFeedSlaves(server.slaves,c->db->id,c->argv,c->argc);
if (listLength(server.monitors))
replicationFeedMonitors(server.monitors,c->db->id,c->argv,c->argc);
}
server.stat_numcommands++; server.stat_numcommands++;
} }
...@@ -1317,7 +1327,7 @@ int processCommand(redisClient *c) { ...@@ -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;
} }
......
...@@ -237,6 +237,13 @@ ...@@ -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); ...@@ -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);
......
...@@ -221,7 +221,8 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { ...@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment