我正在使用远程Actor并尝试实现日志记录......
希望每当Actor尝试重新建立时,我想给出一个随机ID。 我的尝试如下。
class SampleActor @Inject() (implicit system: ActorSystem, ec: ExecutionContext) extends Actor with ActorLogging {
val remote = context.actorSelection(s"akka.tcp://PathToRemoteActor")
val initialIdentifyId = getNextId
remote ! Identify(initialIdentifyId)
def receive = establish(initialIdentifyId)
def doIdentify(nextId: Int) = {
context become establish(nextId)
system.scheduler.scheduleOnce(10.seconds) { remote ! Identify(nextId) }
}
def getNextId = new Random().nextInt(10000)
def establish(identifyId: Int): Actor.Receive = {
case ActorIdentity(`identifyId`, Some(ref)) ⇒
log.info(s"Connection to Remote Actor established with identifyId: $identifyId")
context.watch(ref)
context.become(active(identifyId, ref))
case ActorIdentity(`identifyId`, None) ⇒
log.info(s"Connecting to Remote Actor failed. identifyId: $identifyId")
doIdentify(getNextId)
case foo:Foo ⇒ //do something
}
def active(identifyId: Int, remoteRef: ActorRef): Actor.Receive = {
case Terminated(`remoteRef`) ⇒
context.unwatch(remoteRef)
log.error(s"Remote Actor was disconnected. identifyId: $identifyId")
doIdentify(getNextId)
case foo:Foo => //do something with the remote actor.
}
}
上面的代码是远程actor的客户端。
除了线system.scheduler.scheduleOnce(10.seconds) { remote ! Identify(nextId) }
似乎触发某种心跳连接隐式之外,这正如我预期的那样工作。
如果我一直关闭远程actor,然后开始运行它,然后再次关闭。 akka调试日志将如下所示。
[warn] a.r.ReliableDeliverySupervisor - Association with remote system [akka.tcp://foo-remote@127.0.0.1:2552] has failed, address is now gated for [5000] ms. Reason: [Disassociated]
[info] a.r.RemoteActorRefProvider$RemoteDeadLetterActorRef - Message [akka.remote.RemoteWatcher$Heartbeat$] from Actor[akka://foo-client/system/remote-watcher#1679701185] to Actor[akka://foo-client/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[info] a.r.RemoteActorRefProvider$RemoteDeadLetterActorRef - Message [akka.remote.RemoteWatcher$Heartbeat$] from Actor[akka://foo-client/system/remote-watcher#1679701185] to Actor[akka://foo-client/deadLetters] was not delivered. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[info] a.r.RemoteActorRefProvider$RemoteDeadLetterActorRef - Message [akka.remote.RemoteWatcher$Heartbeat$] from Actor[akka://foo-client/system/remote-watcher#1679701185] to Actor[akka://foo-client/deadLetters] was not delivered. [3] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[info] a.r.RemoteActorRefProvider$RemoteDeadLetterActorRef - Message [akka.remote.RemoteWatcher$Heartbeat$] from Actor[akka://foo-client/system/remote-watcher#1679701185] to Actor[akka://foo-client/deadLetters] was not delivered. [4] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[info] a.r.RemoteActorRefProvider$RemoteDeadLetterActorRef - Message [akka.remote.RemoteWatcher$Heartbeat$] from Actor[akka://foo-client/system/remote-watcher#1679701185] to Actor[akka://foo-client/deadLetters] was not delivered. [5] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
...
如果我删除了行system.scheduler.scheduleOnce(10.seconds) { remote ! Identify(nextId) }
,则只会产生一个心跳死信日志。
如何避免多次心跳?
也许我使用Identify(nextId)
的方式是错误的?
提前致谢。