SCRIPT command for introspection and control of the scripting environment.

This commit is contained in:
antirez 2011-10-24 22:47:00 +02:00
parent ca1f766a55
commit 070e39454d
3 changed files with 51 additions and 4 deletions

View File

@ -215,7 +215,8 @@ struct redisCommand redisCommandTable[] = {
{"client",clientCommand,-2,"ar",0,NULL,0,0,0,0,0}, {"client",clientCommand,-2,"ar",0,NULL,0,0,0,0,0},
{"eval",evalCommand,-3,"wms",0,zunionInterGetKeys,0,0,0,0,0}, {"eval",evalCommand,-3,"wms",0,zunionInterGetKeys,0,0,0,0,0},
{"evalsha",evalShaCommand,-3,"wms",0,zunionInterGetKeys,0,0,0,0,0}, {"evalsha",evalShaCommand,-3,"wms",0,zunionInterGetKeys,0,0,0,0,0},
{"slowlog",slowlogCommand,-2,"r",0,NULL,0,0,0,0,0} {"slowlog",slowlogCommand,-2,"r",0,NULL,0,0,0,0,0},
{"script",scriptCommand,-2,"ras",0,NULL,0,0,0,0,0}
}; };
/*============================ Utility functions ============================ */ /*============================ Utility functions ============================ */
@ -869,6 +870,7 @@ void initServerConfig() {
server.cluster_enabled = 0; server.cluster_enabled = 0;
server.cluster.configfile = zstrdup("nodes.conf"); server.cluster.configfile = zstrdup("nodes.conf");
server.lua_time_limit = REDIS_LUA_TIME_LIMIT; server.lua_time_limit = REDIS_LUA_TIME_LIMIT;
server.lua_client = NULL;
updateLRUClock(); updateLRUClock();
resetServerSaveParams(); resetServerSaveParams();

View File

@ -1128,6 +1128,7 @@ void objectCommand(redisClient *c);
void clientCommand(redisClient *c); void clientCommand(redisClient *c);
void evalCommand(redisClient *c); void evalCommand(redisClient *c);
void evalShaCommand(redisClient *c); void evalShaCommand(redisClient *c);
void scriptCommand(redisClient *c);
#if defined(__GNUC__) #if defined(__GNUC__)
void *calloc(size_t count, size_t size) __attribute__ ((deprecated)); void *calloc(size_t count, size_t size) __attribute__ ((deprecated));

View File

@ -304,6 +304,10 @@ void luaLoadLibraries(lua_State *lua) {
#endif #endif
} }
/* Initialize the scripting environment.
* It is possible to call this function to reset the scripting environment
* assuming that we call scriptingRelease() before.
* See scriptingReset() for more information. */
void scriptingInit(void) { void scriptingInit(void) {
lua_State *lua = lua_open(); lua_State *lua = lua_open();
luaLoadLibraries(lua); luaLoadLibraries(lua);
@ -364,13 +368,29 @@ void scriptingInit(void) {
lua_setglobal(lua,"math"); lua_setglobal(lua,"math");
/* Create the (non connected) client that we use to execute Redis commands /* Create the (non connected) client that we use to execute Redis commands
* inside the Lua interpreter */ * inside the Lua interpreter.
server.lua_client = createClient(-1); * Note: there is no need to create it again when this function is called
server.lua_client->flags |= REDIS_LUA_CLIENT; * by scriptingReset(). */
if (server.lua_client == NULL) {
server.lua_client = createClient(-1);
server.lua_client->flags |= REDIS_LUA_CLIENT;
}
server.lua = lua; server.lua = lua;
} }
/* Release resources related to Lua scripting.
* This function is used in order to reset the scripting environment. */
void scriptingRelease(void) {
dictRelease(server.lua_scripts);
lua_close(server.lua);
}
void scriptingReset(void) {
scriptingRelease();
scriptingInit();
}
/* Hash the scripit into a SHA1 digest. We use this as Lua function name. /* Hash the scripit into a SHA1 digest. We use this as Lua function name.
* Digest should point to a 41 bytes buffer: 40 for SHA1 converted into an * Digest should point to a 41 bytes buffer: 40 for SHA1 converted into an
* hexadecimal number, plus 1 byte for null term. */ * hexadecimal number, plus 1 byte for null term. */
@ -669,3 +689,27 @@ int redis_math_randomseed (lua_State *L) {
redisSrand48(luaL_checkint(L, 1)); redisSrand48(luaL_checkint(L, 1));
return 0; return 0;
} }
/* ---------------------------------------------------------------------------
* SCRIPT command for script environment introspection and control
* ------------------------------------------------------------------------- */
void scriptCommand(redisClient *c) {
if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"flush")) {
scriptingReset();
addReply(c,shared.ok);
server.dirty++; /* Replicating this command is a good idea. */
} else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr,"exists")) {
int j;
addReplyMultiBulkLen(c, c->argc-2);
for (j = 2; j < c->argc; j++) {
if (dictFind(server.lua_scripts,c->argv[j]->ptr))
addReply(c,shared.cone);
else
addReply(c,shared.czero);
}
} else {
addReplyError(c, "Unknown SCRIPT subcommand or wrong # of args.");
}
}