]> git.saurik.com Git - redis.git/commitdiff
SCRIPT command for introspection and control of the scripting environment.
authorantirez <antirez@gmail.com>
Mon, 24 Oct 2011 20:47:00 +0000 (22:47 +0200)
committerantirez <antirez@gmail.com>
Mon, 24 Oct 2011 20:47:00 +0000 (22:47 +0200)
src/redis.c
src/redis.h
src/scripting.c

index 6f52ada2de8387f7050447bec793bcfac4530f2c..f39d25b495ea00d966f2b7af7909daafaf0e8254 100644 (file)
@@ -215,7 +215,8 @@ struct redisCommand redisCommandTable[] = {
     {"client",clientCommand,-2,"ar",0,NULL,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},
-    {"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 ============================ */
@@ -869,6 +870,7 @@ void initServerConfig() {
     server.cluster_enabled = 0;
     server.cluster.configfile = zstrdup("nodes.conf");
     server.lua_time_limit = REDIS_LUA_TIME_LIMIT;
+    server.lua_client = NULL;
 
     updateLRUClock();
     resetServerSaveParams();
index 0f0587e448327a689333a6f5acc74ec7516c963d..d77d5b30efeac5203965203f23f039ea3963770a 100644 (file)
@@ -1128,6 +1128,7 @@ void objectCommand(redisClient *c);
 void clientCommand(redisClient *c);
 void evalCommand(redisClient *c);
 void evalShaCommand(redisClient *c);
+void scriptCommand(redisClient *c);
 
 #if defined(__GNUC__)
 void *calloc(size_t count, size_t size) __attribute__ ((deprecated));
index af22d5015b59f13b8674482f66308c2ae0bd69de..725c123eb739b020e0a5bbab24b094c178b7514e 100644 (file)
@@ -304,6 +304,10 @@ void luaLoadLibraries(lua_State *lua) {
 #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) {
     lua_State *lua = lua_open();
     luaLoadLibraries(lua);
@@ -364,13 +368,29 @@ void scriptingInit(void) {
     lua_setglobal(lua,"math");
 
     /* Create the (non connected) client that we use to execute Redis commands
-     * inside the Lua interpreter */
-    server.lua_client = createClient(-1);
-    server.lua_client->flags |= REDIS_LUA_CLIENT;
+     * inside the Lua interpreter.
+     * Note: there is no need to create it again when this function is called
+     * by scriptingReset(). */
+    if (server.lua_client == NULL) {
+        server.lua_client = createClient(-1);
+        server.lua_client->flags |= REDIS_LUA_CLIENT;
+    }
 
     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.
  * Digest should point to a 41 bytes buffer: 40 for SHA1 converted into an
  * hexadecimal number, plus 1 byte for null term. */
@@ -669,3 +689,27 @@ int redis_math_randomseed (lua_State *L) {
   redisSrand48(luaL_checkint(L, 1));
   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.");
+    }
+}