summaryrefslogtreecommitdiff
path: root/src/sentinel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sentinel.c')
-rw-r--r--src/sentinel.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/sentinel.c b/src/sentinel.c
index b1d843667..25efdf6f3 100644
--- a/src/sentinel.c
+++ b/src/sentinel.c
@@ -3203,21 +3203,53 @@ int sentinelSendSlaveOf(sentinelRedisInstance *ri, char *host, int port) {
ll2string(portstr,sizeof(portstr),port);
+ /* If host is NULL we send SLAVEOF NO ONE that will turn the instance
+ * into a master. */
if (host == NULL) {
host = "NO";
memcpy(portstr,"ONE",4);
}
+ /* In order to send SLAVEOF in a safe way, we send a transaction performing
+ * the following tasks:
+ * 1) Reconfigure the instance according to the specified host/port params.
+ * 2) Rewrite the configuraiton.
+ * 3) Disconnect all clients (but this one sending the commnad) in order
+ * to trigger the ask-master-on-reconnection protocol for connected
+ * clients.
+ *
+ * Note that we don't check the replies returned by commands, since we
+ * will observe instead the effects in the next INFO output. */
+ retval = redisAsyncCommand(ri->cc,
+ sentinelDiscardReplyCallback, NULL, "MULTI");
+ if (retval == REDIS_ERR) return retval;
+ ri->pending_commands++;
+
retval = redisAsyncCommand(ri->cc,
sentinelDiscardReplyCallback, NULL, "SLAVEOF %s %s", host, portstr);
if (retval == REDIS_ERR) return retval;
+ ri->pending_commands++;
+ retval = redisAsyncCommand(ri->cc,
+ sentinelDiscardReplyCallback, NULL, "CONFIG REWRITE");
+ if (retval == REDIS_ERR) return retval;
ri->pending_commands++;
- if (redisAsyncCommand(ri->cc,
- sentinelDiscardReplyCallback, NULL, "CONFIG REWRITE") == REDIS_OK)
- {
- ri->pending_commands++;
- }
+
+ /* CLIENT KILL TYPE <type> is only supported starting from Redis 2.8.12,
+ * however sending it to an instance not understanding this command is not
+ * an issue because CLIENT is variadic command, so Redis will not
+ * recognized as a syntax error, and the transaction will not fail (but
+ * only the unsupported command will fail). */
+ retval = redisAsyncCommand(ri->cc,
+ sentinelDiscardReplyCallback, NULL, "CLIENT KILL TYPE normal");
+ if (retval == REDIS_ERR) return retval;
+ ri->pending_commands++;
+
+ retval = redisAsyncCommand(ri->cc,
+ sentinelDiscardReplyCallback, NULL, "EXEC");
+ if (retval == REDIS_ERR) return retval;
+ ri->pending_commands++;
+
return REDIS_OK;
}