4

我有一个演员,负责监视另一个演员(它是远程的,因此不能直接引用)。它通过使用获取对actor的引用actorSelectionIdentify然后观察结果ActorRef。这样可行。

但是现在我想在其他演员终止时自动重新连接,所以我重用相同actorSelection的(演员在同一位置实例化),但这次查找通过Identify永远失败。我不知道为什么它会起作用,当演员在开始时已经实例化但不是,否则。

编辑: 还有什么奇怪的是,在第一次连接之前存在关联错误,而在尝试重新连接时则没有,即使远程 jvm 完全终止。我刚刚注意到,如果您在失败后等待大约一分钟或更长时间,则关联错误返回并且连接再次成功。有没有办法配置这个(它是缓存吗?)机制。

这是标准行为还是我做错了什么?

万一我的代码搞砸了:

object ServerMonitor {
  case object Request
  case class Reply(ref: ActorRef)
}

class ServerMonitor(path: String) extends Actor with ActorLogging {
  import ServerMonitor._

  var server: Option[ActorRef] = None  
  var listeners: Set[ActorRef] = Set.empty

  def receive = {
    case ActorIdentity("server", Some(ref)) =>
      server = Some(ref)
      context.watch(ref)
      listeners.foreach(_ ! Reply(ref))
      listeners = Set.empty
      log.info(s"connected to the server at $path")

    case ActorIdentity("server", None) =>
      server = None
      log.warning(s"couldnt reach the server at $path")
      import context.dispatcher
      context.system.scheduler.scheduleOnce(1 second) {
        context.actorSelection(path) ! Identify("server")
      }

    case Terminated(ref) =>
      log.warning("server terminated")
      server = None
      context.actorSelection(path) ! Identify("server")

    case Request =>
      server.fold { 
        listeners += sender
      } { ref =>
        sender ! Reply(ref)
      }
  }

  override def preStart() {
    context.actorSelection(path) ! Identify("server")
  }
}
4

1 回答 1

3

好的,我刚刚发现,问题是什么。有一个配置值:

# The length of time to gate an address whose name lookup has failed
# or has explicitly signalled that it will not accept connections
# (remote system is shutting down or the requesting system is quarantined).
# No connection attempts will be made to an address while it remains
# gated. Any messages sent to a gated address will be directed to dead
# letters instead. Name lookups are costly, and the time to recovery
# is typically large, therefore this setting should be a value in the
# order of seconds or minutes.
gate-invalid-addresses-for = 60 s

可以将其设置为低,以允许在远程系统恢复后快速重新连接。即使考虑到上述原因,60 年代对我来说似乎也高得离谱。

于 2013-10-08T15:58:16.283 回答