Publish cluster changes to event bus, see #2202
* ClusterEventBus * Removed register listener and related * Removed Gossip.meta because it doesn't handle version conflicts
This commit is contained in:
parent
9094199011
commit
e38dd80f38
14 changed files with 209 additions and 159 deletions
|
|
@ -16,6 +16,8 @@ import scala.concurrent.Await
|
|||
import scala.concurrent.util.Duration
|
||||
import java.util.concurrent.TimeUnit
|
||||
import akka.remote.testconductor.RoleName
|
||||
import akka.actor.Props
|
||||
import akka.actor.Actor
|
||||
|
||||
object LargeClusterMultiJvmSpec extends MultiNodeConfig {
|
||||
// each jvm simulates a datacenter with many nodes
|
||||
|
|
@ -78,6 +80,7 @@ abstract class LargeClusterSpec
|
|||
with MultiNodeClusterSpec {
|
||||
|
||||
import LargeClusterMultiJvmSpec._
|
||||
import ClusterEvent._
|
||||
|
||||
var systems: IndexedSeq[ActorSystem] = IndexedSeq(system)
|
||||
val nodesPerDatacenter = system.settings.config.getInt(
|
||||
|
|
@ -143,15 +146,16 @@ abstract class LargeClusterSpec
|
|||
|
||||
val latch = TestLatch(clusterNodes.size)
|
||||
clusterNodes foreach { c ⇒
|
||||
c.registerListener(new MembershipChangeListener {
|
||||
override def notify(members: SortedSet[Member]): Unit = {
|
||||
if (!latch.isOpen && members.size == totalNodes && members.forall(_.status == MemberStatus.Up)) {
|
||||
log.debug("All [{}] nodes Up in [{}], it took [{}], received [{}] gossip messages",
|
||||
totalNodes, c.selfAddress, tookMillis, gossipCount(c))
|
||||
latch.countDown()
|
||||
}
|
||||
c.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
if (!latch.isOpen && members.size == totalNodes && members.forall(_.status == MemberStatus.Up)) {
|
||||
log.debug("All [{}] nodes Up in [{}], it took [{}], received [{}] gossip messages",
|
||||
totalNodes, c.selfAddress, tookMillis, gossipCount(c))
|
||||
latch.countDown()
|
||||
}
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
}
|
||||
|
||||
runOn(from) {
|
||||
|
|
@ -271,15 +275,16 @@ abstract class LargeClusterSpec
|
|||
|
||||
val latch = TestLatch(nodesPerDatacenter)
|
||||
systems foreach { sys ⇒
|
||||
Cluster(sys).registerListener(new MembershipChangeListener {
|
||||
override def notify(members: SortedSet[Member]): Unit = {
|
||||
if (!latch.isOpen && members.size == liveNodes && Cluster(sys).latestGossip.overview.unreachable.size == unreachableNodes) {
|
||||
log.info("Detected [{}] unreachable nodes in [{}], it took [{}], received [{}] gossip messages",
|
||||
unreachableNodes, Cluster(sys).selfAddress, tookMillis, gossipCount(Cluster(sys)))
|
||||
latch.countDown()
|
||||
}
|
||||
Cluster(sys).subscribe(sys.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
if (!latch.isOpen && members.size == liveNodes && Cluster(sys).latestGossip.overview.unreachable.size == unreachableNodes) {
|
||||
log.info("Detected [{}] unreachable nodes in [{}], it took [{}], received [{}] gossip messages",
|
||||
unreachableNodes, Cluster(sys).selfAddress, tookMillis, gossipCount(Cluster(sys)))
|
||||
latch.countDown()
|
||||
}
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
}
|
||||
|
||||
runOn(firstDatacenter) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import akka.remote.testkit.MultiNodeConfig
|
|||
import akka.remote.testkit.MultiNodeSpec
|
||||
import akka.testkit._
|
||||
import scala.concurrent.util.duration._
|
||||
import akka.actor.Props
|
||||
import akka.actor.Actor
|
||||
|
||||
object LeaderLeavingMultiJvmSpec extends MultiNodeConfig {
|
||||
val first = role("first")
|
||||
|
|
@ -32,6 +34,7 @@ abstract class LeaderLeavingSpec
|
|||
with MultiNodeClusterSpec {
|
||||
|
||||
import LeaderLeavingMultiJvmSpec._
|
||||
import ClusterEvent._
|
||||
|
||||
val leaderHandoffWaitingTime = 30.seconds
|
||||
|
||||
|
|
@ -66,15 +69,16 @@ abstract class LeaderLeavingSpec
|
|||
val leavingLatch = TestLatch()
|
||||
val exitingLatch = TestLatch()
|
||||
val expectedAddresses = roles.toSet map address
|
||||
cluster.registerListener(new MembershipChangeListener {
|
||||
def notify(members: SortedSet[Member]) {
|
||||
def check(status: MemberStatus): Boolean =
|
||||
(members.map(_.address) == expectedAddresses &&
|
||||
members.exists(m ⇒ m.address == oldLeaderAddress && m.status == status))
|
||||
if (check(MemberStatus.Leaving)) leavingLatch.countDown()
|
||||
if (check(MemberStatus.Exiting)) exitingLatch.countDown()
|
||||
cluster.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
def check(status: MemberStatus): Boolean =
|
||||
(members.map(_.address) == expectedAddresses &&
|
||||
members.exists(m ⇒ m.address == oldLeaderAddress && m.status == status))
|
||||
if (check(MemberStatus.Leaving)) leavingLatch.countDown()
|
||||
if (check(MemberStatus.Exiting)) exitingLatch.countDown()
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
enterBarrier("registered-listener")
|
||||
|
||||
enterBarrier("leader-left")
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import akka.remote.testkit.MultiNodeConfig
|
|||
import akka.remote.testkit.MultiNodeSpec
|
||||
import akka.testkit._
|
||||
import scala.concurrent.util.duration._
|
||||
import akka.actor.Props
|
||||
import akka.actor.Actor
|
||||
|
||||
object MembershipChangeListenerExitingMultiJvmSpec extends MultiNodeConfig {
|
||||
val first = role("first")
|
||||
|
|
@ -36,6 +38,7 @@ abstract class MembershipChangeListenerExitingSpec
|
|||
with MultiNodeClusterSpec {
|
||||
|
||||
import MembershipChangeListenerExitingMultiJvmSpec._
|
||||
import ClusterEvent._
|
||||
|
||||
"A registered MembershipChangeListener" must {
|
||||
"be notified when new node is EXITING" taggedAs LongRunningTest in {
|
||||
|
|
@ -53,12 +56,13 @@ abstract class MembershipChangeListenerExitingSpec
|
|||
|
||||
runOn(third) {
|
||||
val exitingLatch = TestLatch()
|
||||
cluster.registerListener(new MembershipChangeListener {
|
||||
def notify(members: SortedSet[Member]) {
|
||||
if (members.size == 3 && members.exists(m ⇒ m.address == address(second) && m.status == MemberStatus.Exiting))
|
||||
exitingLatch.countDown()
|
||||
cluster.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
if (members.size == 3 && members.exists(m ⇒ m.address == address(second) && m.status == MemberStatus.Exiting))
|
||||
exitingLatch.countDown()
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
enterBarrier("registered-listener")
|
||||
exitingLatch.await
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import akka.remote.testkit.MultiNodeConfig
|
|||
import akka.remote.testkit.MultiNodeSpec
|
||||
import akka.testkit._
|
||||
import scala.concurrent.util.duration._
|
||||
import akka.actor.Props
|
||||
import akka.actor.Actor
|
||||
|
||||
object MembershipChangeListenerJoinMultiJvmSpec extends MultiNodeConfig {
|
||||
val first = role("first")
|
||||
|
|
@ -29,6 +31,7 @@ abstract class MembershipChangeListenerJoinSpec
|
|||
with MultiNodeClusterSpec {
|
||||
|
||||
import MembershipChangeListenerJoinMultiJvmSpec._
|
||||
import ClusterEvent._
|
||||
|
||||
"A registered MembershipChangeListener" must {
|
||||
"be notified when new node is JOINING" taggedAs LongRunningTest in {
|
||||
|
|
@ -36,12 +39,13 @@ abstract class MembershipChangeListenerJoinSpec
|
|||
runOn(first) {
|
||||
val joinLatch = TestLatch()
|
||||
val expectedAddresses = Set(first, second) map address
|
||||
cluster.registerListener(new MembershipChangeListener {
|
||||
def notify(members: SortedSet[Member]) {
|
||||
if (members.map(_.address) == expectedAddresses && members.exists(_.status == MemberStatus.Joining))
|
||||
joinLatch.countDown()
|
||||
cluster.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
if (members.map(_.address) == expectedAddresses && members.exists(_.status == MemberStatus.Joining))
|
||||
joinLatch.countDown()
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
enterBarrier("registered-listener")
|
||||
|
||||
joinLatch.await
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import akka.remote.testkit.MultiNodeConfig
|
|||
import akka.remote.testkit.MultiNodeSpec
|
||||
import akka.testkit._
|
||||
import akka.actor.Address
|
||||
import akka.actor.Props
|
||||
import akka.actor.Actor
|
||||
|
||||
object MembershipChangeListenerLeavingMultiJvmSpec extends MultiNodeConfig {
|
||||
val first = role("first")
|
||||
|
|
@ -34,6 +36,7 @@ abstract class MembershipChangeListenerLeavingSpec
|
|||
with MultiNodeClusterSpec {
|
||||
|
||||
import MembershipChangeListenerLeavingMultiJvmSpec._
|
||||
import ClusterEvent._
|
||||
|
||||
"A registered MembershipChangeListener" must {
|
||||
"be notified when new node is LEAVING" taggedAs LongRunningTest in {
|
||||
|
|
@ -52,13 +55,14 @@ abstract class MembershipChangeListenerLeavingSpec
|
|||
runOn(third) {
|
||||
val latch = TestLatch()
|
||||
val expectedAddresses = Set(first, second, third) map address
|
||||
cluster.registerListener(new MembershipChangeListener {
|
||||
def notify(members: SortedSet[Member]) {
|
||||
if (members.map(_.address) == expectedAddresses &&
|
||||
members.exists(m ⇒ m.address == address(second) && m.status == MemberStatus.Leaving))
|
||||
latch.countDown()
|
||||
cluster.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
if (members.map(_.address) == expectedAddresses &&
|
||||
members.exists(m ⇒ m.address == address(second) && m.status == MemberStatus.Leaving))
|
||||
latch.countDown()
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
enterBarrier("registered-listener")
|
||||
latch.await
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import com.typesafe.config.ConfigFactory
|
|||
import akka.remote.testkit.MultiNodeConfig
|
||||
import akka.remote.testkit.MultiNodeSpec
|
||||
import akka.testkit._
|
||||
import akka.actor.Props
|
||||
import akka.actor.Actor
|
||||
|
||||
object MembershipChangeListenerUpMultiJvmSpec extends MultiNodeConfig {
|
||||
val first = role("first")
|
||||
|
|
@ -26,6 +28,7 @@ abstract class MembershipChangeListenerUpSpec
|
|||
with MultiNodeClusterSpec {
|
||||
|
||||
import MembershipChangeListenerUpMultiJvmSpec._
|
||||
import ClusterEvent._
|
||||
|
||||
"A set of connected cluster systems" must {
|
||||
|
||||
|
|
@ -36,12 +39,13 @@ abstract class MembershipChangeListenerUpSpec
|
|||
runOn(first, second) {
|
||||
val latch = TestLatch()
|
||||
val expectedAddresses = Set(first, second) map address
|
||||
cluster.registerListener(new MembershipChangeListener {
|
||||
def notify(members: SortedSet[Member]) {
|
||||
if (members.map(_.address) == expectedAddresses && members.forall(_.status == MemberStatus.Up))
|
||||
latch.countDown()
|
||||
cluster.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
if (members.map(_.address) == expectedAddresses && members.forall(_.status == MemberStatus.Up))
|
||||
latch.countDown()
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
enterBarrier("listener-1-registered")
|
||||
cluster.join(first)
|
||||
latch.await
|
||||
|
|
@ -58,12 +62,13 @@ abstract class MembershipChangeListenerUpSpec
|
|||
|
||||
val latch = TestLatch()
|
||||
val expectedAddresses = Set(first, second, third) map address
|
||||
cluster.registerListener(new MembershipChangeListener {
|
||||
def notify(members: SortedSet[Member]) {
|
||||
if (members.map(_.address) == expectedAddresses && members.forall(_.status == MemberStatus.Up))
|
||||
latch.countDown()
|
||||
cluster.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
if (members.map(_.address) == expectedAddresses && members.forall(_.status == MemberStatus.Up))
|
||||
latch.countDown()
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
enterBarrier("listener-2-registered")
|
||||
|
||||
runOn(third) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import akka.remote.testkit.MultiNodeConfig
|
|||
import akka.remote.testkit.MultiNodeSpec
|
||||
import akka.testkit._
|
||||
import scala.concurrent.util.duration._
|
||||
import akka.actor.Props
|
||||
import akka.actor.Actor
|
||||
|
||||
object NodeLeavingAndExitingMultiJvmSpec extends MultiNodeConfig {
|
||||
val first = role("first")
|
||||
|
|
@ -32,6 +34,7 @@ abstract class NodeLeavingAndExitingSpec
|
|||
with MultiNodeClusterSpec {
|
||||
|
||||
import NodeLeavingAndExitingMultiJvmSpec._
|
||||
import ClusterEvent._
|
||||
|
||||
"A node that is LEAVING a non-singleton cluster" must {
|
||||
|
||||
|
|
@ -44,15 +47,16 @@ abstract class NodeLeavingAndExitingSpec
|
|||
val leavingLatch = TestLatch()
|
||||
val exitingLatch = TestLatch()
|
||||
val expectedAddresses = roles.toSet map address
|
||||
cluster.registerListener(new MembershipChangeListener {
|
||||
def notify(members: SortedSet[Member]) {
|
||||
def check(status: MemberStatus): Boolean =
|
||||
(members.map(_.address) == expectedAddresses &&
|
||||
members.exists(m ⇒ m.address == secondAddess && m.status == status))
|
||||
if (check(MemberStatus.Leaving)) leavingLatch.countDown()
|
||||
if (check(MemberStatus.Exiting)) exitingLatch.countDown()
|
||||
cluster.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
def check(status: MemberStatus): Boolean =
|
||||
(members.map(_.address) == expectedAddresses &&
|
||||
members.exists(m ⇒ m.address == secondAddess && m.status == status))
|
||||
if (check(MemberStatus.Leaving)) leavingLatch.countDown()
|
||||
if (check(MemberStatus.Exiting)) exitingLatch.countDown()
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
enterBarrier("registered-listener")
|
||||
|
||||
runOn(third) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import akka.testkit._
|
|||
import scala.concurrent.util.duration._
|
||||
import scala.collection.immutable.SortedSet
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import akka.actor.Props
|
||||
import akka.actor.Actor
|
||||
|
||||
object NodeUpMultiJvmSpec extends MultiNodeConfig {
|
||||
val first = role("first")
|
||||
|
|
@ -27,6 +29,7 @@ abstract class NodeUpSpec
|
|||
with MultiNodeClusterSpec {
|
||||
|
||||
import NodeUpMultiJvmSpec._
|
||||
import ClusterEvent._
|
||||
|
||||
"A cluster node that is joining another cluster" must {
|
||||
"be moved to UP by the leader after a convergence" taggedAs LongRunningTest in {
|
||||
|
|
@ -39,12 +42,13 @@ abstract class NodeUpSpec
|
|||
"be unaffected when joining again" taggedAs LongRunningTest in {
|
||||
|
||||
val unexpected = new AtomicReference[SortedSet[Member]](SortedSet.empty)
|
||||
cluster.registerListener(new MembershipChangeListener {
|
||||
def notify(members: SortedSet[Member]) {
|
||||
if (members.size != 2 || members.exists(_.status != MemberStatus.Up))
|
||||
unexpected.set(members)
|
||||
cluster.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
if (members.size != 2 || members.exists(_.status != MemberStatus.Up))
|
||||
unexpected.set(members)
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
enterBarrier("listener-registered")
|
||||
|
||||
runOn(second) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import akka.testkit._
|
|||
import scala.concurrent.util.duration._
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import scala.collection.immutable.SortedSet
|
||||
import akka.actor.Props
|
||||
import akka.actor.Actor
|
||||
|
||||
object SunnyWeatherMultiJvmSpec extends MultiNodeConfig {
|
||||
val first = role("first")
|
||||
|
|
@ -40,6 +42,7 @@ abstract class SunnyWeatherSpec
|
|||
with MultiNodeClusterSpec {
|
||||
|
||||
import SunnyWeatherMultiJvmSpec._
|
||||
import ClusterEvent._
|
||||
|
||||
"A normal cluster" must {
|
||||
"be healthy" taggedAs LongRunningTest in {
|
||||
|
|
@ -55,12 +58,13 @@ abstract class SunnyWeatherSpec
|
|||
log.info("5 joined")
|
||||
|
||||
val unexpected = new AtomicReference[SortedSet[Member]]
|
||||
cluster.registerListener(new MembershipChangeListener {
|
||||
def notify(members: SortedSet[Member]) {
|
||||
// we don't expected any changes to the cluster
|
||||
unexpected.set(members)
|
||||
cluster.subscribe(system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case MembersChanged(members) ⇒
|
||||
// we don't expected any changes to the cluster
|
||||
unexpected.set(members)
|
||||
}
|
||||
})
|
||||
})), classOf[MembersChanged])
|
||||
|
||||
for (n ← 1 to 30) {
|
||||
enterBarrier("period-" + n)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue