Buffer LeaderChanged events and publish all on convergence, see #3017

* Otherwise some changes might never be published, since it doesn't have
  to be convergence on all nodes inbetween all transitions.
* Detected by a failure ClusterSingletonManagerSpec.
* Added a test to simulate the failure scenario.
This commit is contained in:
Patrik Nordwall 2013-02-08 09:17:55 +01:00
parent 4ee299c729
commit d32a2edc51
3 changed files with 80 additions and 44 deletions

View file

@ -339,7 +339,7 @@ private[cluster] final class ClusterDomainEventPublisher extends Actor with Acto
var latestGossip: Gossip = Gossip.empty
var latestConvergedGossip: Gossip = Gossip.empty
var memberEvents: immutable.Seq[MemberEvent] = immutable.Seq.empty
var bufferedEvents: immutable.IndexedSeq[ClusterDomainEvent] = Vector.empty
def receive = {
case PublishChanges(newGossip) publishChanges(newGossip)
@ -401,14 +401,16 @@ private[cluster] final class ClusterDomainEventPublisher extends Actor with Acto
val newMemberEvents = diffMemberEvents(oldGossip, newGossip)
convertToInstantMemberEvents(newMemberEvents) foreach publish
// buffer up the MemberEvents waiting for convergence
memberEvents ++= newMemberEvents
// if we have convergence then publish the MemberEvents and possibly a LeaderChanged
bufferedEvents ++= newMemberEvents
// buffer up the LeaderChanged waiting for convergence
bufferedEvents ++= diffLeader(oldGossip, newGossip)
// if we have convergence then publish the MemberEvents and LeaderChanged
if (newGossip.convergence) {
val previousConvergedGossip = latestConvergedGossip
latestConvergedGossip = newGossip
memberEvents foreach { event
bufferedEvents foreach { event
event match {
case m @ (MemberDowned(_) | MemberRemoved(_))
case m: MemberEvent if m.isInstanceOf[MemberDowned] || m.isInstanceOf[MemberRemoved]
// TODO MemberDowned match should probably be covered by MemberRemoved, see ticket #2788
// but right now we don't change Downed to Removed
publish(event)
@ -417,8 +419,7 @@ private[cluster] final class ClusterDomainEventPublisher extends Actor with Acto
case _ publish(event)
}
}
memberEvents = immutable.Seq.empty
diffLeader(previousConvergedGossip, latestConvergedGossip) foreach publish
bufferedEvents = Vector.empty
}
// publish internal SeenState for testing purposes
diffSeen(oldGossip, newGossip) foreach publish