我的应用程序中有一个单独的actor系统,这完全正常,除了在同一个JVM中加载和卸载相同的应用程序进行测试时,我有一个错误,因为我尝试在我的启动过程中重新创建已经存在的演员。
因此,我得到akka.actor.InvalidActorNameException
,因为Actor名称不是唯一的。
我正在寻找一种方法来根据actor系统顺利关闭actor,而无需关闭actor系统本身。这是一个合理的策略吗?
答案 0 :(得分:1)
这不完全是你问题的答案 - “ ......一种顺畅关闭演员的方法...... ”,但是你提到你能够在同一个节目中启动两个应用程序JVM。
你能否让你的actor系统在应用程序实例中成为 singleton而不是整个JVM中的singleton?
您将拥有两个独立的actor系统,您不会有名称冲突,也不必启动/停止特定的actor。
我想问题可能是一些演员正在与外界互动,例如从JMS等消费一些消息。那么哪个演员系统正在处理它们就不明显了。
答案 1 :(得分:0)
你想要这样的事吗?
object AkkaTest extends App {
import akka.actor._
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
val system = ActorSystem.create
val supervisor = system.actorOf(Props[MasterOfPuppets], name = "masterOfPuppets")
private object AllTerminated
private class MasterOfPuppets extends Actor {
var supervised = 0
var waiterForTerminated: Option[ActorRef] = None
def receive = {
case actor: ActorRef =>
context.watch(actor)
supervised += 1
case Terminated(dead) =>
supervised -= 1
if (supervised == 0) {
waiterForTerminated.map(_ ! AllTerminated)
waiterForTerminated = None
}
case AllTerminated =>
if (supervised == 0) {
sender ! AllTerminated
} else {
waiterForTerminated = Some(sender)
}
}
}
private class TestedActor extends Actor {
def receive = {
case a: Any => sender ! a
}
}
implicit val timeout = Timeout(5.seconds) // needed for `?` below
// Create first actor
val actor1 = system.actorOf(Props[TestedActor], name = "name1")
supervisor ! actor1
actor1 ! PoisonPill
val waitForIt = supervisor ? AllTerminated
Await.result(waitForIt, 5.seconds)
// Same name
val actor2 = system.actorOf(Props[TestedActor], name = "name1")
supervisor ! actor2
println("ok then")
}
你的问题非常简单:Akka和消息是异步的。如果您在杀死他之后尝试创建一个演员,则该名称不可用。 在创建新actor之前尝试一下Thread.sleep,它将起作用.. :))