我有一个演员,负责监视另一个演员(它是远程的,因此不能直接引用)。它通过使用获取对actor的引用actorSelection
,Identify
然后观察结果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")
}
}