From 2e5181ef28ff0db00cca013ba7986456bd1d32d0 Mon Sep 17 00:00:00 2001 From: Josh Hershberg Date: Sun, 5 Nov 2023 10:47:57 +0200 Subject: [PATCH] Cluster refactor: Add failover cmd support to cluster api The failover command is up until now not supported in cluster mode. This commit allows a cluster implementation to support the command. The legacy clustering implementation still does not support this command. Signed-off-by: Josh Hershberg --- src/cluster.h | 2 ++ src/cluster_legacy.c | 26 +++++++++++++++++++++----- src/replication.c | 12 +++++++----- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/cluster.h b/src/cluster.h index 9f6e482f4..8b8feb24e 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -96,6 +96,8 @@ char* clusterNodeHostname(clusterNode *node); const char *getPreferredEndpoint(clusterNode *n); void migrateCommand(client *c); long long getReplOffset(clusterNode *node); +int clusterAllowFailoverCmd(client *c); +void clusterPromoteSelfToMaster(void); char **clusterDebugCommandHelp(void); ConnectionType *connTypeOfCluster(void); diff --git a/src/cluster_legacy.c b/src/cluster_legacy.c index 0fd8b0a20..72ab7428a 100644 --- a/src/cluster_legacy.c +++ b/src/cluster_legacy.c @@ -6400,11 +6400,27 @@ long long getReplOffset(clusterNode *node) { } const char *getPreferredEndpoint(clusterNode *n) { - char* hostname = clusterNodeHostname(n); - switch(server.cluster_preferred_endpoint_type) { - case CLUSTER_ENDPOINT_TYPE_IP: return clusterNodeIp(n); - case CLUSTER_ENDPOINT_TYPE_HOSTNAME: return (hostname != NULL && hostname[0] != '\0') ? hostname : "?"; - case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: return ""; + char *hostname = clusterNodeHostname(n); + switch (server.cluster_preferred_endpoint_type) { + case CLUSTER_ENDPOINT_TYPE_IP: + return clusterNodeIp(n); + case CLUSTER_ENDPOINT_TYPE_HOSTNAME: + return (hostname != NULL && hostname[0] != '\0') ? hostname : "?"; + case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: + return ""; } return "unknown"; } + +int clusterAllowFailoverCmd(client *c) { + if (!server.cluster_enabled) { + return 1; + } + addReplyError(c,"FAILOVER not allowed in cluster mode. " + "Use CLUSTER FAILOVER command instead."); + return 0; +} + +void clusterPromoteSelfToMaster(void) { + replicationUnsetMaster(); +} diff --git a/src/replication.c b/src/replication.c index e64251663..e4b7c42e1 100644 --- a/src/replication.c +++ b/src/replication.c @@ -951,7 +951,11 @@ void syncCommand(client *c) { } if (!strcasecmp(c->argv[1]->ptr,server.replid)) { - replicationUnsetMaster(); + if (server.cluster_enabled) { + clusterPromoteSelfToMaster(); + } else { + replicationUnsetMaster(); + } sds client = catClientInfoString(sdsempty(),c); serverLog(LL_NOTICE, "MASTER MODE enabled (failover request from '%s')",client); @@ -4061,12 +4065,10 @@ void abortFailover(const char *err) { * will attempt forever and must be manually aborted. */ void failoverCommand(client *c) { - if (server.cluster_enabled) { - addReplyError(c,"FAILOVER not allowed in cluster mode. " - "Use CLUSTER FAILOVER command instead."); + if (!clusterAllowFailoverCmd(c)) { return; } - + /* Handle special case for abort */ if ((c->argc == 2) && !strcasecmp(c->argv[1]->ptr,"abort")) { if (server.failover_state == NO_FAILOVER) {