// Immediately after the entry is appended to the log, apply the joint
// configuration. Cluster membership changes do not wait for commitment.
// Since we're using a joint consensus, it's safe to work with all members
// of both the old and new configuration without causing split elections.
context.clusterManager().cluster().update(jointConfig, null);
context.events().membershipChange().handle(new MembershipChangeEvent(jointConfig.getMembers()));
LOGGER.debug("{} - Updated internal cluster configuration {}", context.clusterManager().localNode(), context.clusterManager().cluster());
// Once the cluster is updated, the replicator will be notified and update its
// internal connections. Then we commit the joint configuration and allow
// it to be replicated to all the nodes in the updated cluster.
LOGGER.debug("{} - Committing all entries for configuration change", context.clusterManager().localNode());
replicator.commit(configIndex).whenComplete((commitIndex2, commitError2) -> {
// Now that we've gotten to this point, we know that the combined cluster
// membership has been replicated to a majority of the cluster.
// Append the new user configuration to the log and force all replicas
// to be synchronized.
ConfigurationEntry newConfigEntry = new ConfigurationEntry(context.currentTerm(), userConfig);
long newConfigIndex = context.log().appendEntry(newConfigEntry);
LOGGER.debug("{} - Appended {} to log at index {}", context.clusterManager().localNode(), newConfigEntry, newConfigIndex);
// Again, once we've appended the new configuration to the log, update
// the local internal configuration.
context.clusterManager().cluster().update(userConfig, null);
context.events().membershipChange().handle(new MembershipChangeEvent(userConfig.getMembers()));
LOGGER.debug("{} - Updated internal cluster configuration {}", context.clusterManager().localNode(), context.clusterManager().cluster());
// Note again that when the cluster membership changes, the replicator will
// be notified and remove any replicas that are no longer a part of the cluster.
// Now that the cluster and replicator have been updated, we can commit the