Commit baee5650 authored by antirez's avatar antirez
Browse files

Multiple fixes for EVAL (issue #872).

1) The event handler was no restored after a timeout condition if the
   command was eventually executed with success.
2) The command was not converted to EVAL in case of errors in the middle
   of the execution.
3) Terrible duplication of code without any apparent reason.
parent d7740fc8
...@@ -787,7 +787,7 @@ void evalGenericCommand(redisClient *c, int evalsha) { ...@@ -787,7 +787,7 @@ void evalGenericCommand(redisClient *c, int evalsha) {
lua_State *lua = server.lua; lua_State *lua = server.lua;
char funcname[43]; char funcname[43];
long long numkeys; long long numkeys;
int delhook = 0; int delhook = 0, err;
/* We want the same PRNG sequence at every call so that our PRNG is /* We want the same PRNG sequence at every call so that our PRNG is
* not affected by external state. */ * not affected by external state. */
...@@ -869,7 +869,9 @@ void evalGenericCommand(redisClient *c, int evalsha) { ...@@ -869,7 +869,9 @@ void evalGenericCommand(redisClient *c, int evalsha) {
/* At this point whatever this script was never seen before or if it was /* At this point whatever this script was never seen before or if it was
* already defined, we can call it. We have zero arguments and expect * already defined, we can call it. We have zero arguments and expect
* a single return value. */ * a single return value. */
if (lua_pcall(lua,0,1,0)) { err = lua_pcall(lua,0,1,0);
/* Perform some cleanup that we need to do both on error and success. */
if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */ if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
if (server.lua_timedout) { if (server.lua_timedout) {
server.lua_timedout = 0; server.lua_timedout = 0;
...@@ -880,18 +882,17 @@ void evalGenericCommand(redisClient *c, int evalsha) { ...@@ -880,18 +882,17 @@ void evalGenericCommand(redisClient *c, int evalsha) {
} }
server.lua_caller = NULL; server.lua_caller = NULL;
selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */ selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
lua_gc(lua,LUA_GCSTEP,1);
if (err) {
addReplyErrorFormat(c,"Error running script (call to %s): %s\n", addReplyErrorFormat(c,"Error running script (call to %s): %s\n",
funcname, lua_tostring(lua,-1)); funcname, lua_tostring(lua,-1));
lua_pop(lua,1); lua_pop(lua,1); /* Consume the Lua reply. */
lua_gc(lua,LUA_GCCOLLECT,0); } else {
return; /* On success convert the Lua return value into Redis protocol, and
} * send it to * the client. */
if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
server.lua_timedout = 0;
server.lua_caller = NULL;
selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
luaReplyToRedisReply(c,lua); luaReplyToRedisReply(c,lua);
lua_gc(lua,LUA_GCSTEP,1); }
/* If we have slaves attached we want to replicate this command as /* If we have slaves attached we want to replicate this command as
* EVAL instead of EVALSHA. We do this also in the AOF as currently there * EVAL instead of EVALSHA. We do this also in the AOF as currently there
......
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