Skip to content
Snippets Groups Projects
Commit 46cc3dbd authored by Serge Petrenko's avatar Serge Petrenko Committed by Serge Petrenko
Browse files

replication: refactor replicaset_connect()

replicaset_connect() sleeps in a loop while waiting for the connections
to be established and checks a bunch of conditions in between the loop
cycles to check if it can proceed (with either a success or a failure).

The conditions are already quite complicated and multiple, but it's
going to get worse with the addition of bootstrap_strategy "config" and
"supervised": during bootstrap replicaset_connect() will proceed as soon
as the configured bootstrap leader is connected.

Factor all these checks out to a helper function for simplicity.

Part-of #7999

NO_DOC=refactoring
NO_TEST=refactoring
NO_CHANGELOG=refactoring
parent 03e3428f
No related branches found
No related tags found
No related merge requests found
......@@ -890,6 +890,31 @@ applier_on_connect_f(struct trigger *trigger, void *event)
return 0;
}
/** A helper determining whether any more connection attempts are needed. */
static bool
replicaset_is_connected(struct replicaset_connect_state *state, int count,
bool connect_quorum)
{
if (state->connected == count)
return true;
/*
* After a quorum is reached, it is considered enough to proceed. Except
* if a connection is critical. Connection *is* critical even with 0
* quorum when the instance starts first time and needs to choose
* replicaset UUID, fill _cluster, etc. If 0 quorum allowed to return
* immediately even at first start, then it would be impossible to
* bootstrap a replicaset - all nodes would start immediately and choose
* different cluster UUIDs.
*/
if (state->connected >= replicaset_connect_quorum(count) &&
!connect_quorum) {
return true;
}
if (count - state->failed < replicaset_connect_quorum(count))
return true;
return false;
}
void
replicaset_connect(struct applier **appliers, int count,
bool connect_quorum, bool keep_connect)
......@@ -905,6 +930,7 @@ replicaset_connect(struct applier **appliers, int count,
if (!connect_quorum) {
/*
* Enter orphan mode on configuration change and
*
* only leave it when we manage to sync with
* replicaset_quorum instances. Don't change
* title though, it should be 'loading' during
......@@ -949,28 +975,10 @@ replicaset_connect(struct applier **appliers, int count,
applier_start(applier);
}
while (state.connected < count) {
/*
* After a quorum is reached, it is considered
* enough to proceed. Except if a connection is
* critical.
* Connection *is* critical even with 0 quorum
* when the instance starts first time and needs
* to choose replicaset UUID, fill _cluster, etc.
* If 0 quorum allowed to return immediately even
* at first start, then it would be impossible to
* bootstrap a replicaset - all nodes would start
* immediately and choose different cluster UUIDs.
*/
if (state.connected >= replicaset_connect_quorum(count) &&
!connect_quorum) {
break;
}
while (!replicaset_is_connected(&state, count, connect_quorum)) {
double wait_start = ev_monotonic_now(loop());
if (fiber_cond_wait_timeout(&state.wakeup, timeout) != 0)
break;
if (count - state.failed < replicaset_connect_quorum(count))
break;
timeout -= ev_monotonic_now(loop()) - wait_start;
}
if (state.connected < count) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment