0

我的应用程序中有一个单例参与者系统,除了在同一个 JVM 中加载和卸载同一个应用程序进行测试时,我有一个错误,因为我在启动过程中尝试重新创建一个参与者已经存在。

结果,我得到了一个,akka.actor.InvalidActorNameException因为 Actor 名称不是唯一的。

我正在寻找一种方法来根据演员系统顺利关闭演员,而无需关闭演员系统本身。哪个是合理的策略?

4

2 回答 2

1

这并不完全回答您的问题 - “ ......一种平滑关闭演员的方法...... ”,但您提到您能够在同一个 JVM 中启动两个应用程序。

你能让你的actor系统在应用程序实例中成为单例而不是整个JVM中的单例吗?

您将拥有两个独立的演员系统,不会有名称冲突,也不必启动/停止特定的演员。

我想问题可能是如果某些参与者正在与外部世界交互,例如从 JMS 消费一些消息等。那么哪个参与者系统正在处理它们就不是很明显了。

于 2013-02-17T12:26:23.497 回答
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 和消息是异步的。如果您在杀死他之后尝试创建一个演员,则该名称不可用。在创建新演员之前尝试一个 Thread.sleep ,它将起作用.. :)

于 2013-02-11T11:05:13.533 回答