Use Either for LeaderChanged state, see #2518

This commit is contained in:
Patrik Nordwall 2012-09-20 08:44:44 +02:00
parent 6cf638815f
commit ab8a690c65

View file

@ -173,8 +173,14 @@ private[cluster] final class ClusterDomainEventPublisher extends Actor with Acto
import InternalClusterAction._ import InternalClusterAction._
var latestGossip: Gossip = Gossip() var latestGossip: Gossip = Gossip()
var stashedLeaderChanged: Option[LeaderChanged] = None
var publishedLeaderChanged: Option[LeaderChanged] = None // Keep track of LeaderChanged event. Should not be published until
// convergence, and it should only be published when leader actually
// changed to another node. 3 states:
// - None: No LeaderChanged detected yet, nothing published yet
// - Some(Left): Stashed LeaderChanged to be published later, when convergence
// - Some(Right): Latest published LeaderChanged
var leaderChangedState: Option[Either[LeaderChanged, LeaderChanged]] = None
def receive = { def receive = {
case PublishChanges(oldGossip, newGossip) publishChanges(oldGossip, newGossip) case PublishChanges(oldGossip, newGossip) publishChanges(oldGossip, newGossip)
@ -204,23 +210,26 @@ private[cluster] final class ClusterDomainEventPublisher extends Actor with Acto
latestGossip = newGossip latestGossip = newGossip
diff(oldGossip, newGossip) foreach { event diff(oldGossip, newGossip) foreach { event
event match { event match {
case x @ LeaderChanged(_) if Some(x) == publishedLeaderChanged case x @ LeaderChanged(_) if leaderChangedState == Some(Right(x))
// skip, this leader has already been published // skip, this leader has already been published
case x @ LeaderChanged(_) if oldGossip.convergence && newGossip.convergence case x @ LeaderChanged(_) if oldGossip.convergence && newGossip.convergence
stashedLeaderChanged = None // leader changed and immediate convergence
publishedLeaderChanged = Some(x) leaderChangedState = Some(Right(x))
eventStream publish x eventStream publish x
case x: LeaderChanged case x: LeaderChanged
// publish later, when convergence // publish later, when convergence
stashedLeaderChanged = Some(x) leaderChangedState = Some(Left(x))
case ConvergenceChanged(true) case ConvergenceChanged(true)
stashedLeaderChanged foreach { // now it's convergence, publish eventual stashed LeaderChanged event
publishedLeaderChanged = stashedLeaderChanged leaderChangedState match {
stashedLeaderChanged = None case Some(Left(x))
eventStream publish _ leaderChangedState = Some(Right(x))
eventStream publish x
case _ // nothing stashed
} }
eventStream publish event eventStream publish event
@ -228,7 +237,10 @@ private[cluster] final class ClusterDomainEventPublisher extends Actor with Acto
eventStream publish event eventStream publish event
// notify DeathWatch about unreachable node // notify DeathWatch about unreachable node
eventStream publish AddressTerminated(m.address) eventStream publish AddressTerminated(m.address)
case _ eventStream publish event
case _
// all other events
eventStream publish event
} }
} }
} }