RATIS-1558. Support Listener in RaftServerImpl#627
Conversation
|
@szetszwo Can you help review this patch, thanks! |
szetszwo
left a comment
There was a problem hiding this comment.
@codings-dan , thanks a lot for working on this. It looks good in general. Some comments inlined.
| if (roles.equals(RaftPeerRole.FOLLOWER)) { | ||
| reason = "startAsFollower"; | ||
| setRole(RaftPeerRole.FOLLOWER, reason); | ||
| } else if (roles.equals(RaftPeerRole.LISTENER)) { |
There was a problem hiding this comment.
Since RaftPeerRole is enum, use == . Also, let's add an else-clause to throw an exception.
if (newRole == RaftPeerRole.FOLLOWER) {
reason = "startAsFollower";
setRole(RaftPeerRole.FOLLOWER, reason);
} else if (newRole == RaftPeerRole.LISTENER) {
reason = "startAsListener";
setRole(RaftPeerRole.LISTENER, reason);
} else {
throw new IllegalArgumentException("Unexpected role " + newRole);
}
|
|
||
| if (old != RaftPeerRole.FOLLOWER || force) { | ||
| setRole(RaftPeerRole.FOLLOWER, reason); | ||
| if (old != RaftPeerRole.LISTENER) { |
There was a problem hiding this comment.
It is illegal to have old == LISTENER. Let's throw an exception in the beginning. Then we don't have to change other code in this method.
@@ -485,6 +498,9 @@ class RaftServerImpl implements RaftServer.Division,
*/
private synchronized boolean changeToFollower(long newTerm, boolean force, Object reason) {
final RaftPeerRole old = role.getCurrentRole();
+ if (old == RaftPeerRole.LISTENER) {
+ throw new IllegalStateException("Unexpected role " + old);
+ }
final boolean metadataUpdated = state.updateCurrentTerm(newTerm);
There was a problem hiding this comment.
Thanks for pointing out this problem, in theory, old will not be a Listener, I have fixed it
| followerState = updateLastRpcTime(FollowerState.UpdateType.APPEND_START); | ||
|
|
||
| // Check that the append entries are not inconsistent. There are 3 | ||
| // Check that the append ents are not inconsistent. There are 3 |
There was a problem hiding this comment.
Sorry for causing this typo , i have fixed it
| public void run() { | ||
| final TimeDuration sleepDeviationThreshold = server.getSleepDeviationThreshold(); | ||
| while (isRunning && server.getInfo().isFollower()) { | ||
| while (isRunning && (server.getInfo().isFollower() || server.getInfo().isListener())) { |
There was a problem hiding this comment.
Let's add a shouldRun() method.
@@ -109,10 +110,19 @@ class FollowerState extends Daemon {
return true;
}
+ private boolean shouldRun() {
+ final DivisionInfo info = server.getInfo();
+ final boolean run = isRunning && (info.isFollower() || info.isListener());
+ if (!run) {
+ LOG.info("{}: Stopping now (isRunning? {}, role = {})", this, isRunning, info.getCurrentRole());
+ }
+ return run;
+ }
+
@Override
public void run() {
final TimeDuration sleepDeviationThreshold = server.getSleepDeviationThreshold();
- while (isRunning && server.getInfo().isFollower()) {
+ while (shouldRun()) {
final TimeDuration electionTimeout = server.getRandomElectionTimeout();
try {
final TimeDuration extraSleep = electionTimeout.sleep();
| final boolean isPeer = (server.getInfo().isFollower() || server.getInfo().isListener()); | ||
| if (!isRunning || !isPeer) { | ||
| LOG.info("{}: Stopping now (isRunning? {}, isPeer? {})", this, isRunning, isPeer); |
There was a problem hiding this comment.
Use shouldRun() from above.
|
@szetszwo Thanks for reviewing the code, I change the code according to the comment you left, PTAL again, thank you! BTW, in my opinion, apart from adding a admin command to change the listener to follower using the |
|
@codings-dan , thanks a lot for working on the Listener! We should add some tests to make sure the following.
|
szetszwo
left a comment
There was a problem hiding this comment.
+1 the change looks good.
will do, thanks for the guidance! |
@szetszwo This part doesn't seem to do anything since we don't send a requestVote request to the listener, see Thanks again for the guidance. I add unit test related to leaderElection, see #737 |
|
@codings-dan , thanks a lot for working on the listener feature!
We should not depend on that. A patient problem is that a server may be misconfigured or do not have the up-to-date configuration. Then, it may send a requestVote to listeners, which it thinks they are voting members. If the listeners replied yes, the server will become a leader. |
What changes were proposed in this pull request?
subtask to support listener: Support Listener in RaftServerImpl
What is the link to the Apache JIRA
https://issues.apache.org/jira/projects/RATIS/issues/RATIS-1558?filter=reportedbyme
How was this patch tested?
UT