Avoid concurrent raft membership changes #7565
Conversation
server/raft.go
Outdated
| return false | ||
| } | ||
| for _, v := range ae.entries { | ||
| if v.Type == EntryAddPeer || v.Type == EntryRemovePeer { |
There was a problem hiding this comment.
Do we need to include EntryPeerState here too?
e1f4aa2 to
39c8e6d
Compare
|
This could be considered complete.
|
|
My primary worry with only disallowing membership in Raft is that we'll be protected against concurrent changes on the lowest level. But the user issuing |
3bcf2f6 to
53ef284
Compare
MauriceVanVeen
left a comment
There was a problem hiding this comment.
Generally LGTM, but could you try removing these loops in monitorStream and monitorConsumer that are used for scale moves and see if the tests still pass? Since that in essence would still rely on being able to do concurrent membership changes.
for _, p := range oldPeers {
n.ProposeRemovePeer(p)
}Avoid concurrent peer additions and removals by having the leader check that there are no uncommitted entries of type EntryAddPeer or EntryRemovePeer. Signed-off-by: Daniele Sciascia <daniele@nats.io>
53ef284 to
434b02b
Compare
Removed the loops with a call to ProposeKnownPeers() |
ProposeRemovePeer can no longer be used in tight loops without error checking, because it can't handle more than one membership change at a time. Replacing those loops in the stream / consumer move scenarios with an equivalent call to ProposeKnownPeers. Signed-off-by: Daniele Sciascia <daniele@nats.io>
30c3907 to
3cb9017
Compare
A simple approach based to avoid concurrent membership changes. The leader simply drops a membership change if there is another membership change in progress. A membership is in progress if it has been proposed, but not committed yet.
Signed-off-by: Daniele Sciascia daniele@nats.io