]> git.saurik.com Git - redis.git/commitdiff
First implementation of the ASKING command. Semantics still to verify.
authorantirez <antirez@gmail.com>
Mon, 17 Oct 2011 15:35:23 +0000 (17:35 +0200)
committerantirez <antirez@gmail.com>
Mon, 17 Oct 2011 15:35:23 +0000 (17:35 +0200)
src/cluster.c
src/networking.c
src/redis.c
src/redis.h

index d16427428f3e59b29945dfb55eff6f1fa28def09..ccb230c91777f338062842ef64c18e5580c7807b 100644 (file)
@@ -1657,6 +1657,19 @@ void dumpCommand(redisClient *c) {
     return;
 }
 
+/* The ASKING command is required after a -ASK redirection.
+ * The client should issue ASKING before to actualy send the command to
+ * the target instance. See the Redis Cluster specification for more
+ * information. */
+void askingCommand(redisClient *c) {
+    if (server.cluster_enabled == 0) {
+        addReplyError(c,"This instance has cluster support disabled");
+        return;
+    }
+    c->flags |= REDIS_ASKING;
+    addReply(c,shared.ok);
+}
+
 /* -----------------------------------------------------------------------------
  * Cluster functions related to serving / redirecting clients
  * -------------------------------------------------------------------------- */
@@ -1750,9 +1763,12 @@ clusterNode *getNodeByQuery(redisClient *c, struct redisCommand *cmd, robj **arg
     }
     /* Handle the case in which we are receiving this hash slot from
      * another instance, so we'll accept the query even if in the table
-     * it is assigned to a different node. */
-    if (server.cluster.importing_slots_from[slot] != NULL)
+     * it is assigned to a different node, but only if the client
+     * issued an ASKING command before. */
+    if (server.cluster.importing_slots_from[slot] != NULL &&
+        c->flags & REDIS_ASKING) {
         return server.cluster.myself;
+    }
     /* It's not a -ASK case. Base case: just return the right node. */
     return n;
 }
index f14b4ef8cec2a371fb4dce84402893ee946ffd63..7ed5c6fcf3ab4d64377eb81912aa6f5001f1791b 100644 (file)
@@ -625,6 +625,8 @@ void resetClient(redisClient *c) {
     c->reqtype = 0;
     c->multibulklen = 0;
     c->bulklen = -1;
+    /* We clear the ASKING flag as well if we are not inside a MULTI. */
+    if (!(c->flags & REDIS_MULTI)) c->flags &= (~REDIS_ASKING);
 }
 
 void closeTimedoutClients(void) {
index dd693f6c37e1ca759e3610fc34abf58bfb2964e9..6f52ada2de8387f7050447bec793bcfac4530f2c 100644 (file)
@@ -209,6 +209,7 @@ struct redisCommand redisCommandTable[] = {
     {"cluster",clusterCommand,-2,"ar",0,NULL,0,0,0,0,0},
     {"restore",restoreCommand,4,"awm",0,NULL,1,1,1,0,0},
     {"migrate",migrateCommand,6,"aw",0,NULL,0,0,0,0,0},
+    {"asking",askingCommand,1,"r",0,NULL,0,0,0,0,0},
     {"dump",dumpCommand,2,"ar",0,NULL,0,0,0,0,0},
     {"object",objectCommand,-2,"r",0,NULL,0,0,0,0,0},
     {"client",clientCommand,-2,"ar",0,NULL,0,0,0,0,0},
index af08145e6b819ae03cbbf1938d0bb7f099fc8e0f..0f0587e448327a689333a6f5acc74ec7516c963d 100644 (file)
 #define REDIS_UNBLOCKED 256 /* This client was unblocked and is stored in
                                server.unblocked_clients */
 #define REDIS_LUA_CLIENT 512 /* This is a non connected client used by Lua */
+#define REDIS_ASKING 1024   /* Client issued the ASKING command */
 
 /* Client request types */
 #define REDIS_REQ_INLINE 1
@@ -1121,6 +1122,7 @@ void unwatchCommand(redisClient *c);
 void clusterCommand(redisClient *c);
 void restoreCommand(redisClient *c);
 void migrateCommand(redisClient *c);
+void askingCommand(redisClient *c);
 void dumpCommand(redisClient *c);
 void objectCommand(redisClient *c);
 void clientCommand(redisClient *c);