[Tarantool-patches] [PATCH v2 7/9] replication: introduce a new election mode: "manual"
Serge Petrenko
sergepetrenko at tarantool.org
Mon Apr 12 22:40:20 MSK 2021
When an instance is configured in "manual" election mode, it behaves as
a voter for most of the time, until `box.ctl.promote()` is called.
Once `box.ctl.promote()` is called the instance will behave as a
candidate for a full election round, e.g. until the leader is known. If
the instance wins the elections, it remains in `leader` state until the
next elections. Otherwise the instance returns to `voter` state.
Follow-up #5445
Part of #3055
---
src/box/box.cc | 37 +++++++++++++++++---------
src/box/raft.c | 2 ++
src/box/raft.h | 17 ++++++++++++
test/replication/election_basic.result | 4 +--
4 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/src/box/box.cc b/src/box/box.cc
index aae57ec29..b77b0a08d 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -680,17 +680,27 @@ box_check_uri(const char *source, const char *option_name)
}
}
-static const char *
+static enum election_mode
box_check_election_mode(void)
{
const char *mode = cfg_gets("election_mode");
- if (mode == NULL || (strcmp(mode, "off") != 0 &&
- strcmp(mode, "voter") != 0 && strcmp(mode, "candidate") != 0)) {
- diag_set(ClientError, ER_CFG, "election_mode", "the value must "
- "be a string 'off' or 'voter' or 'candidate'");
- return NULL;
- }
- return mode;
+ if (mode == NULL)
+ goto error;
+
+ if (strcmp(mode, "off") == 0)
+ return ELECTION_MODE_OFF;
+ else if (strcmp(mode, "voter") == 0)
+ return ELECTION_MODE_VOTER;
+ else if (strcmp(mode, "manual") == 0)
+ return ELECTION_MODE_MANUAL;
+ else if (strcmp(mode, "candidate") == 0)
+ return ELECTION_MODE_CANDIDATE;
+
+error:
+ diag_set(ClientError, ER_CFG, "election_mode",
+ "the value must be one of the following strings: "
+ "'off', 'voter', 'candidate', 'manual'");
+ return ELECTION_MODE_INVALID;
}
static double
@@ -1113,7 +1123,7 @@ box_check_config(void)
box_check_uri(cfg_gets("listen"), "listen");
box_check_instance_uuid(&uuid);
box_check_replicaset_uuid(&uuid);
- if (box_check_election_mode() == NULL)
+ if (box_check_election_mode() == ELECTION_MODE_INVALID)
diag_raise();
if (box_check_election_timeout() < 0)
diag_raise();
@@ -1147,11 +1157,12 @@ box_check_config(void)
int
box_set_election_mode(void)
{
- const char *mode = box_check_election_mode();
- if (mode == NULL)
+ enum election_mode mode = box_check_election_mode();
+ if (mode == ELECTION_MODE_INVALID)
return -1;
- raft_cfg_is_candidate(box_raft(), strcmp(mode, "candidate") == 0);
- raft_cfg_is_enabled(box_raft(), strcmp(mode, "off") != 0);
+ box_election_mode = mode;
+ raft_cfg_is_candidate(box_raft(), mode == ELECTION_MODE_CANDIDATE);
+ raft_cfg_is_enabled(box_raft(), mode != ELECTION_MODE_OFF);
return 0;
}
diff --git a/src/box/raft.c b/src/box/raft.c
index cfd898db0..285dbe4fd 100644
--- a/src/box/raft.c
+++ b/src/box/raft.c
@@ -44,6 +44,8 @@ struct raft box_raft_global = {
.state = 0,
};
+enum election_mode box_election_mode = ELECTION_MODE_INVALID;
+
/**
* A trigger executed each time the Raft state machine updates any
* of its visible attributes.
diff --git a/src/box/raft.h b/src/box/raft.h
index 1c59f17e6..15f4e80d9 100644
--- a/src/box/raft.h
+++ b/src/box/raft.h
@@ -35,8 +35,25 @@
extern "C" {
#endif
+enum election_mode {
+ ELECTION_MODE_INVALID = -1,
+ ELECTION_MODE_OFF = 0,
+ ELECTION_MODE_VOTER = 1,
+ ELECTION_MODE_MANUAL = 2,
+ ELECTION_MODE_CANDIDATE = 3,
+};
+
struct raft_request;
+/**
+ * box_election_mode - current mode of operation for raft. Some modes correspond
+ * to RAFT operation modes directly, like CANDIDATE, VOTER and OFF.
+ * There's a mode which does not map to raft operation mode directly:
+ * MANUAL. In this mode RAFT usually operates as a voter, but it may become a
+ * candidate for some period of time when user calls `box.ctl.promote()`
+ */
+extern enum election_mode box_election_mode;
+
/** Raft state of this instance. */
static inline struct raft *
box_raft(void)
diff --git a/test/replication/election_basic.result b/test/replication/election_basic.result
index 4d7d33f2b..d5320b3ff 100644
--- a/test/replication/election_basic.result
+++ b/test/replication/election_basic.result
@@ -22,8 +22,8 @@ box.cfg{election_mode = 100}
| ...
box.cfg{election_mode = '100'}
| ---
- | - error: 'Incorrect value for option ''election_mode'': the value must be a string
- | ''off'' or ''voter'' or ''candidate'''
+ | - error: 'Incorrect value for option ''election_mode'': the value must be one of the
+ | following strings: ''off'', ''voter'', ''candidate'', ''manual'''
| ...
box.cfg{election_timeout = -1}
| ---
--
2.24.3 (Apple Git-128)
More information about the Tarantool-patches
mailing list