Commit 9f772cc2 authored by antirez's avatar antirez
Browse files

Return errors if a write command is called inside a Lua script after a random...

Return errors if a write command is called inside a Lua script after a random command was called. See https://github.com/antirez/redis/issues/95 for more information.
parent 15ef6053
......@@ -623,6 +623,8 @@ struct redisServer {
dict *lua_scripts; /* A dictionary of SHA1 -> Lua scripts */
long long lua_time_limit;
long long lua_time_start;
int lua_random_dirty; /* True if a random command was called during the
exection of the current script. */
};
typedef struct pubsubPattern {
......
......@@ -180,6 +180,14 @@ int luaRedisCommand(lua_State *lua) {
goto cleanup;
}
if (cmd->flags & REDIS_CMD_WRITE && server.lua_random_dirty) {
luaPushError(lua,
"Write commands not allowed after non deterministic commands");
goto cleanup;
}
if (cmd->flags & REDIS_CMD_RANDOM) server.lua_random_dirty = 1;
/* Run the command */
cmd->proc(c);
......@@ -425,6 +433,16 @@ void evalGenericCommand(redisClient *c, int evalsha) {
* not affected by external state. */
redisSrand48(0);
/* We set this flag to zero to remember that so far no random command
* was called. This way we can allow the user to call commands like
* SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command
* is called (otherwise the replication and AOF would end with non
* deterministic sequences).
*
* Thanks to this flag we'll raise an error every time a write command
* is called after a random command was used. */
server.lua_random_dirty = 0;
/* Get the number of arguments that are keys */
if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != REDIS_OK)
return;
......
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