2015-06-01 25 views
1

我正在使用Plays play.api.mvc.WebSocket s与akka.contrib.pattern.DistributedPubSub事件组合,并且此工作正常。Akka在停止演员之前等待Ack

class SomeSocketActor(out: ActorRef) extends Actor { 
    val mediator = DistributedPubSubExtension(context.system).mediator 
    mediator ! Subscribe("some_group", self) 

    def receive: Actor.Receive = { 
     case SubscribeAck(Subscribe("some_group", None, `self`)) => 
     context become ready 
    } 

    def ready: Actor.Receive = { 
     // ... 
    } 

    override def postStop(): Unit = { 
     mediator ! Unsubscribe("some_group", self) 
    } 
} 

一旦套接字关闭,它会发送Unsubscribe。一旦Unsubscribe收到DistributedPubSubMediator它回答UnsubscribeAck。然而,因为在那一刻(这是postStop后)演员已经停止,UnsubscribeAck移动Akkas一纸空文邮箱和我的日志垃圾邮件的东西,如:

消息 [akka.contrib.pattern.DistributedPubSubMediator演员[akka:// application/system/websockets/24/handler#325798268]是 没有投递。[演员表] [演员表] [演员表] [演员表[012]] [1]遇到了死信。此日志记录可以是 关闭或通过配置设置 'akka.log-dead-letters'和'akka.log-dead-letters-during-shutdown'进行调整。

我知道我只能按照日志消息中的建议,但这似乎不是好的做法。有没有什么办法可以告诉postStop方法中的演员在停止之前等待UnsubscribeAck

回答

0

不在postStop方法中,这太晚了。

但不是接收UnsubscribeAck你可以只become只是在等待UnsubscribeAck,当你收到它(或超时后,万一UnsubscribeAck从未收到停止。

+0

谢谢你的回答。我同意这将是处理一般关机的好方法。但是,当使用'play.api.mvc.WebSocket'时,演员会被Play API创建,管理和关闭,并且我无法影响演员的停止。我希望还有其他方法可以解决这个问题,比如告诉Unsubscribe,对'UnsubscribeAck'没有兴趣。 – miho

+1

在这种情况下,您可以“观看”演员。当它停止时,观察者将收到Terminated消息并且可以发送'Unsubscribe'而不是停止的actor的'postStop'。观察者然后可以接收'UnsubscribeAck'。或者,如果您真的只想忽略UnsubscribeAck,那么让已停止的actor将'sender'设置为'Unsubscribe'给它的父节点,以便父节点接收'UnsubscribeAck'。 –

0

这实际上应该之前停止因为DistributedPubSubMediator在您订阅时注意到您的演员为Terminated。在一个新项目中,它确实按预期工作,并且调解员为您取消订阅,因此您可能不需要做任何事情。它不会在我的项目中这样做,它可能会影响其他人

我的' m正在写第二个长期存在的角色(可以在控制器中创建它),并让WebSocket角色与之交谈以管理订阅。这样新的演员可以传递取消订阅消息,然后它可以接收并忽略UnsubscribeAck