=clu #13875 Fix regression in leader selection

* The leader is selected by picking the first reachable member, but in
  #13875 we had to let the self member be unreachable in the Reachability
  table and that was not considered in the logic of the leader selection.
* That means changed behavior that is unwanted, especially when there
  is only one node left the leader could be evaluated to None instead
  of Some(selfUniqueAddress).
* Note that #13875 has not been released yet.
This commit is contained in:
Patrik Nordwall 2015-03-06 14:29:26 +01:00
parent 109187e364
commit fe98dae650
5 changed files with 34 additions and 22 deletions

View file

@ -271,20 +271,20 @@ object ClusterEvent {
/**
* INTERNAL API
*/
private[cluster] def diffLeader(oldGossip: Gossip, newGossip: Gossip): immutable.Seq[LeaderChanged] = {
val newLeader = newGossip.leader
if (newLeader != oldGossip.leader) List(LeaderChanged(newLeader.map(_.address)))
private[cluster] def diffLeader(oldGossip: Gossip, newGossip: Gossip, selfUniqueAddress: UniqueAddress): immutable.Seq[LeaderChanged] = {
val newLeader = newGossip.leader(selfUniqueAddress)
if (newLeader != oldGossip.leader(selfUniqueAddress)) List(LeaderChanged(newLeader.map(_.address)))
else Nil
}
/**
* INTERNAL API
*/
private[cluster] def diffRolesLeader(oldGossip: Gossip, newGossip: Gossip): Set[RoleLeaderChanged] = {
private[cluster] def diffRolesLeader(oldGossip: Gossip, newGossip: Gossip, selfUniqueAddress: UniqueAddress): Set[RoleLeaderChanged] = {
for {
role (oldGossip.allRoles ++ newGossip.allRoles)
newLeader = newGossip.roleLeader(role)
if newLeader != oldGossip.roleLeader(role)
newLeader = newGossip.roleLeader(role, selfUniqueAddress)
if newLeader != oldGossip.roleLeader(role, selfUniqueAddress)
} yield RoleLeaderChanged(role, newLeader.map(_.address))
}
@ -354,8 +354,9 @@ private[cluster] final class ClusterDomainEventPublisher extends Actor with Acto
members = latestGossip.members,
unreachable = unreachable,
seenBy = latestGossip.seenBy.map(_.address),
leader = latestGossip.leader.map(_.address),
roleLeaderMap = latestGossip.allRoles.map(r r -> latestGossip.roleLeader(r).map(_.address))(collection.breakOut))
leader = latestGossip.leader(selfUniqueAddress).map(_.address),
roleLeaderMap = latestGossip.allRoles.map(r r -> latestGossip.roleLeader(r, selfUniqueAddress)
.map(_.address))(collection.breakOut))
receiver ! state
}
@ -390,8 +391,8 @@ private[cluster] final class ClusterDomainEventPublisher extends Actor with Acto
diffMemberEvents(oldGossip, newGossip) foreach pub
diffUnreachable(oldGossip, newGossip, selfUniqueAddress) foreach pub
diffReachable(oldGossip, newGossip, selfUniqueAddress) foreach pub
diffLeader(oldGossip, newGossip) foreach pub
diffRolesLeader(oldGossip, newGossip) foreach pub
diffLeader(oldGossip, newGossip, selfUniqueAddress) foreach pub
diffRolesLeader(oldGossip, newGossip, selfUniqueAddress) foreach pub
// publish internal SeenState for testing purposes
diffSeen(oldGossip, newGossip, selfUniqueAddress) foreach pub
diffReachability(oldGossip, newGossip) foreach pub