diff options
author | Salvatore Sanfilippo <antirez@gmail.com> | 2019-12-19 09:06:28 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-19 09:06:28 +0100 |
commit | 9a7b6a9f51939e09576b3e26be2da6d6ac20f097 (patch) | |
tree | 87bc60579279162c3206dd093d83e63ad18df0d7 | |
parent | f4b81970601ee138af13f66d62ad10eabe56f41c (diff) | |
parent | 73841e8c495ec4917a8cdee3cbef6fb83433f018 (diff) | |
download | redis-9a7b6a9f51939e09576b3e26be2da6d6ac20f097.tar.gz |
Merge pull request #5780 from soloestoy/lua-multi-more-clear
scripting: flag lua_client as CLIENT_MULTI after redis.replicate_command() immediately
-rw-r--r-- | src/scripting.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/src/scripting.c b/src/scripting.c index 98d4b2b7e..43e01f372 100644 --- a/src/scripting.c +++ b/src/scripting.c @@ -485,13 +485,6 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { static size_t cached_objects_len[LUA_CMD_OBJCACHE_SIZE]; static int inuse = 0; /* Recursive calls detection. */ - /* Reflect MULTI state */ - if (server.lua_multi_emitted || (server.lua_caller->flags & CLIENT_MULTI)) { - c->flags |= CLIENT_MULTI; - } else { - c->flags &= ~CLIENT_MULTI; - } - /* By using Lua debug hooks it is possible to trigger a recursive call * to luaRedisGenericCommand(), which normally should never happen. * To make this function reentrant is futile and makes it slower, but @@ -715,6 +708,9 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { { execCommandPropagateMulti(server.lua_caller); server.lua_multi_emitted = 1; + /* Now we are in the MULTI context, the lua_client should be + * flag as CLIENT_MULTI. */ + c->flags |= CLIENT_MULTI; } /* Run the command */ @@ -1441,6 +1437,22 @@ void luaMaskCountHook(lua_State *lua, lua_Debug *ar) { } } +void prepareLuaClient(void) { + /* Select the right DB in the context of the Lua client */ + selectDb(server.lua_client,server.lua_caller->db->id); + server.lua_client->resp = 2; /* Default is RESP2, scripts can change it. */ + + /* If we are in MULTI context, flag Lua client as CLIENT_MULTI. */ + if (server.lua_caller->flags & CLIENT_MULTI) { + server.lua_client->flags |= CLIENT_MULTI; + } +} + +void resetLuaClient(void) { + /* After the script done, remove the MULTI state. */ + server.lua_client->flags &= ~CLIENT_MULTI; +} + void evalGenericCommand(client *c, int evalsha) { lua_State *lua = server.lua; char funcname[43]; @@ -1529,10 +1541,6 @@ void evalGenericCommand(client *c, int evalsha) { luaSetGlobalArray(lua,"KEYS",c->argv+3,numkeys); luaSetGlobalArray(lua,"ARGV",c->argv+3+numkeys,c->argc-3-numkeys); - /* Set the Lua client database and protocol. */ - selectDb(server.lua_client,c->db->id); - server.lua_client->resp = 2; /* Default is RESP2, scripts can change it. */ - /* Set a hook in order to be able to stop the script execution if it * is running for too much time. * We set the hook only if the time limit is enabled as the hook will @@ -1552,11 +1560,15 @@ void evalGenericCommand(client *c, int evalsha) { delhook = 1; } + prepareLuaClient(); + /* At this point whether this script was never seen before or if it was * already defined, we can call it. We have zero arguments and expect * a single return value. */ err = lua_pcall(lua,0,1,-2); + resetLuaClient(); + /* Perform some cleanup that we need to do both on error and success. */ if (delhook) lua_sethook(lua,NULL,0,0); /* Disable hook */ if (server.lua_timedout) { |