pekko/akka-cluster/src/test/scala/akka/cluster/routing/WeightedRouteesSpec.scala
Patrik Nordwall 84ade6fdc3 add CoordinatedShutdown, #21537
* CoordinatedShutdown that can run tasks for configured phases in order (DAG)
* coordinate handover/shutdown of singleton with cluster exiting/shutdown
* phase config obj with depends-on list
* integrate graceful leaving of sharding in coordinated shutdown
* add timeout and recover
* add some missing artery ports to tests
* leave via CoordinatedShutdown.run
* optionally exit-jvm in last phase
* run via jvm shutdown hook
* send ExitingConfirmed to leader before shutdown of Exiting
  to not have to wait for failure detector to mark it as
  unreachable before removing
* the unreachable signal is still kept as a safe guard if
  message is lost or leader dies
* PhaseClusterExiting vs MemberExited in ClusterSingletonManager
* terminate ActorSystem when cluster shutdown (via Down)
* add more predefined and custom phases
* reference documentation
* migration guide
* problem when the leader order was sys2, sys1, sys3,
  then sys3 could not perform it's duties and move Leving sys1 to
  Exiting because it was observing sys1 as unreachable
* exclude Leaving with exitingConfirmed from convergence condidtion
2017-01-16 09:01:57 +01:00

102 lines
3.3 KiB
Scala

/**
* Copyright (C) 2009-2017 Lightbend Inc. <http://www.lightbend.com>
*/
package akka.cluster.routing
import com.typesafe.config.ConfigFactory
import akka.actor.Address
import akka.actor.RootActorPath
import akka.remote.RARP
import akka.testkit.AkkaSpec
import akka.routing.ActorSelectionRoutee
import akka.routing.ActorRefRoutee
class WeightedRouteesSpec extends AkkaSpec(ConfigFactory.parseString("""
akka.actor.provider = "cluster"
akka.remote.netty.tcp.port = 0
akka.remote.artery.canonical.port = 0
""")) {
val protocol =
if (RARP(system).provider.remoteSettings.Artery.Enabled) "akka"
else "akka.tcp"
val a1 = Address(protocol, "sys", "a1", 2551)
val b1 = Address(protocol, "sys", "b1", 2551)
val c1 = Address(protocol, "sys", "c1", 2551)
val d1 = Address(protocol, "sys", "d1", 2551)
val routeeA = ActorSelectionRoutee(system.actorSelection(RootActorPath(a1) / "user" / "a"))
val routeeB = ActorSelectionRoutee(system.actorSelection(RootActorPath(b1) / "user" / "b"))
val routeeC = ActorSelectionRoutee(system.actorSelection(RootActorPath(c1) / "user" / "c"))
val routees = Vector(routeeA, routeeB, routeeC)
val testActorRoutee = ActorRefRoutee(testActor)
"WeightedRoutees" must {
"allocate weighted routees" in {
val weights = Map(a1 1, b1 3, c1 10)
val weighted = new WeightedRoutees(routees, a1, weights)
weighted(1) should ===(routeeA)
2 to 4 foreach { weighted(_) should ===(routeeB) }
5 to 14 foreach { weighted(_) should ===(routeeC) }
weighted.total should ===(14)
}
"check boundaries" in {
val empty = new WeightedRoutees(Vector(), a1, Map.empty)
empty.isEmpty should ===(true)
intercept[IllegalArgumentException] {
empty.total
}
val empty2 = new WeightedRoutees(Vector(routeeA), a1, Map(a1 0))
empty2.isEmpty should ===(true)
intercept[IllegalArgumentException] {
empty2.total
}
intercept[IllegalArgumentException] {
empty2(0)
}
val weighted = new WeightedRoutees(routees, a1, Map.empty)
weighted.total should ===(3)
intercept[IllegalArgumentException] {
weighted(0)
}
intercept[IllegalArgumentException] {
weighted(4)
}
}
"allocate routees for undefined weight" in {
val weights = Map(a1 1, b1 7)
val weighted = new WeightedRoutees(routees, a1, weights)
weighted(1) should ===(routeeA)
2 to 8 foreach { weighted(_) should ===(routeeB) }
// undefined, uses the mean of the weights, i.e. 4
9 to 12 foreach { weighted(_) should ===(routeeC) }
weighted.total should ===(12)
}
"allocate weighted local routees" in {
val weights = Map(a1 2, b1 1, c1 10)
val routees2 = Vector(testActorRoutee, routeeB, routeeC)
val weighted = new WeightedRoutees(routees2, a1, weights)
1 to 2 foreach { weighted(_) should ===(testActorRoutee) }
3 to weighted.total foreach { weighted(_) should not be (testActorRoutee) }
}
"not allocate ref with weight zero" in {
val weights = Map(a1 0, b1 2, c1 10)
val weighted = new WeightedRoutees(routees, a1, weights)
1 to weighted.total foreach { weighted(_) should not be (routeeA) }
}
}
}