diff --git a/akka-cluster-tools/src/main/scala/akka/cluster/singleton/ClusterSingletonProxy.scala b/akka-cluster-tools/src/main/scala/akka/cluster/singleton/ClusterSingletonProxy.scala index b35ae4fae6..e1417d1c6c 100644 --- a/akka-cluster-tools/src/main/scala/akka/cluster/singleton/ClusterSingletonProxy.scala +++ b/akka-cluster-tools/src/main/scala/akka/cluster/singleton/ClusterSingletonProxy.scala @@ -222,8 +222,13 @@ final class ClusterSingletonProxy(singletonManagerPath: String, settings: Cluste def receive = { // cluster logic case state: CurrentClusterState ⇒ handleInitial(state) - case MemberUp(m) ⇒ add(m) - case mEvent: MemberEvent if mEvent.isInstanceOf[MemberExited] || mEvent.isInstanceOf[MemberRemoved] ⇒ remove(mEvent.member) + case MemberUp(m) ⇒ add(m) + case MemberExited(m) ⇒ remove(m) + case MemberRemoved(m, _) ⇒ + if (m.uniqueAddress == cluster.selfUniqueAddress) + context.stop(self) + else + remove(m) case _: MemberEvent ⇒ // do nothing // singleton identification logic diff --git a/akka-cluster-tools/src/multi-jvm/scala/akka/cluster/singleton/ClusterSingletonManagerLeaveSpec.scala b/akka-cluster-tools/src/multi-jvm/scala/akka/cluster/singleton/ClusterSingletonManagerLeaveSpec.scala index 0aa88140cb..6d73e8db01 100644 --- a/akka-cluster-tools/src/multi-jvm/scala/akka/cluster/singleton/ClusterSingletonManagerLeaveSpec.scala +++ b/akka-cluster-tools/src/multi-jvm/scala/akka/cluster/singleton/ClusterSingletonManagerLeaveSpec.scala @@ -89,12 +89,14 @@ class ClusterSingletonManagerLeaveSpec extends MultiNodeSpec(ClusterSingletonMan name = "echo") } + val echoProxyTerminatedProbe = TestProbe() + lazy val echoProxy: ActorRef = { - system.actorOf( + echoProxyTerminatedProbe.watch(system.actorOf( ClusterSingletonProxy.props( singletonManagerPath = "/user/echo", settings = ClusterSingletonProxySettings(system)), - name = "echoProxy") + name = "echoProxy")) } "Leaving ClusterSingletonManager" must { @@ -136,6 +138,7 @@ class ClusterSingletonManagerLeaveSpec extends MultiNodeSpec(ClusterSingletonMan // CoordinatedShutdown makes sure that singleton actors are // stopped before Cluster shutdown expectMsg("MemberRemoved") + echoProxyTerminatedProbe.expectTerminated(echoProxy, 10.seconds) } enterBarrier("first-stopped") @@ -163,6 +166,7 @@ class ClusterSingletonManagerLeaveSpec extends MultiNodeSpec(ClusterSingletonMan expectMsg(15.seconds, "stop") expectMsg("postStop") expectMsg("MemberRemoved") + echoProxyTerminatedProbe.expectTerminated(echoProxy, 10.seconds) } enterBarrier("second-stopped") @@ -177,6 +181,7 @@ class ClusterSingletonManagerLeaveSpec extends MultiNodeSpec(ClusterSingletonMan expectMsg(5.seconds, "stop") expectMsg("postStop") expectMsg("MemberRemoved") + echoProxyTerminatedProbe.expectTerminated(echoProxy, 10.seconds) } enterBarrier("third-stopped")