4

別のアクターを監視するアクターがあります (これはリモートであるため、直接参照することはできません)。actorSelectionandを使用してアクターへの参照を取得しIdentify、結果の を監視しActorRefます。それはうまくいきます。

しかし、他のアクターが終了したときと同じように自動的に再接続したいので、同じものを再利用しactorSelectionます (アクターは同じ場所でインスタンス化されます) が、今回はルックアップ経由でIdentify永遠に失敗します。アクターが最初にすでにインスタンス化されているがそうでない場合、なぜそれが機能するのか、私には手がかりがありません。

編集: リモートjvmが完全に終了しているにもかかわらず、最初の接続の前に関連付けエラーが発生するのに対し、再接続しようとするとエラーが発生しないことも奇妙です。失敗してから約 1 分以上待つと、関連付けエラーが返され、接続が再び成功することに気付きました。これを構成する方法はありますか (キャッシュですか?) メカニズム。

それは標準的な動作ですか、それとも何か問題がありましたか?

コードで何かを台無しにした場合:

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 に答える