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
This commit is contained in:
parent
4a9c753710
commit
84ade6fdc3
69 changed files with 1778 additions and 339 deletions
|
|
@ -184,7 +184,11 @@ abstract class ClusterShardingLeavingSpec(config: ClusterShardingLeavingSpecConf
|
|||
enterBarrier("after-3")
|
||||
}
|
||||
|
||||
"recover after leaving coordinator node" in within(30.seconds) {
|
||||
"recover after leaving coordinator node" in {
|
||||
system.actorSelection(node(first) / "user" / "shardLocations") ! GetLocations
|
||||
val Locations(originalLocations) = expectMsgType[Locations]
|
||||
val firstAddress = node(first).address
|
||||
|
||||
runOn(third) {
|
||||
cluster.leave(node(first).address)
|
||||
}
|
||||
|
|
@ -196,18 +200,17 @@ abstract class ClusterShardingLeavingSpec(config: ClusterShardingLeavingSpecConf
|
|||
enterBarrier("stopped")
|
||||
|
||||
runOn(second, third, fourth) {
|
||||
system.actorSelection(node(first) / "user" / "shardLocations") ! GetLocations
|
||||
val Locations(locations) = expectMsgType[Locations]
|
||||
val firstAddress = node(first).address
|
||||
awaitAssert {
|
||||
val probe = TestProbe()
|
||||
locations.foreach {
|
||||
case (id, ref) ⇒
|
||||
region.tell(Ping(id), probe.ref)
|
||||
if (ref.path.address == firstAddress)
|
||||
probe.expectMsgType[ActorRef](1.second) should not be (ref)
|
||||
else
|
||||
probe.expectMsg(1.second, ref) // should not move
|
||||
within(15.seconds) {
|
||||
awaitAssert {
|
||||
val probe = TestProbe()
|
||||
originalLocations.foreach {
|
||||
case (id, ref) ⇒
|
||||
region.tell(Ping(id), probe.ref)
|
||||
if (ref.path.address == firstAddress)
|
||||
probe.expectMsgType[ActorRef](1.second) should not be (ref)
|
||||
else
|
||||
probe.expectMsg(1.second, ref) // should not move
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue