mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 00:28:26 -05:00
Sentinel: send SLAVEOF with MULTI, CLIENT KILL, CONFIG REWRITE.
This implements the new Sentinel-Client protocol for the Sentinel part: now instances are reconfigured using a transaction that ensures that the config is rewritten in the target instance, and that clients lose the connection with the instance, in order to be forced to: ask Sentinel, reconnect to the instance, and verify the instance role with the new ROLE command.
This commit is contained in:
parent
bb2011d992
commit
2c17591224
@ -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)
|
||||
{
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user