Ods*_*dsh 6 actor akka akka.net
我正在使用 Akka.NET 来实现一个角色系统,其中一些角色是按需创建的,并在可配置的空闲期后被删除(为此我使用了 Akka 的“ReceiveTimeout”机制)。这些actor中的每一个都由一个key来标识,并且不应该存在两个具有相同key的actor。
这些演员目前由一个共同的监督者创建和删除。可以要求监督者返回对与给定键匹配的演员的引用,通过返回现有的或创建新的(如果具有此键的演员尚不存在)。当演员收到“ReceiveTimeout”消息时,它会通知主管,主管又会用“PoisonPill”杀死它。
在删除消息后立即向其中一个演员发送消息时,我遇到了问题。我注意到向死者发送消息不会产生异常。更糟糕的是,当发送“Ask”消息时,发送者仍然处于阻塞状态,无限期地(或直到超时)等待他永远不会收到的响应。
我首先想到了 Akka 的“Deatchwatch”机制来监控演员的生命周期。但是,如果我没记错的话,垂死的actor发送的“Terminated”消息会像任何其他消息一样被监控actor异步接收,所以问题可能仍然出现在目标actor的死亡和它的接收之间“已终止”消息。
为了解决这个问题,我这样做是为了让任何要求主管提供对此类演员的引用的人都必须向主管发送“关闭会话”消息以在他不再需要演员时释放他(这是透明地完成的)通过一次性“ActorSession”对象)。只要演员上有任何打开的会话,主管就不会删除它。
我想这种情况很常见,因此我想知道是否没有更简单的模式来解决此类问题。任何建议将不胜感激。
我通过 Akka 的Cluster Sharding机制创建的实体 Actor 解决了这个问题:
如果实体的状态是持久的,您可以停止不使用的实体以减少内存消耗。这是通过实体参与者的应用程序特定实现来完成的,例如通过定义接收超时(context.setReceiveTimeout)。如果实体停止自身时消息已排队到实体中,则邮箱中排队的消息将被删除。为了支持优雅的钝化而不丢失此类消息,实体参与者可以将 ShardRegion.Passivate 发送到其父分片。Passivate 中指定的包装消息将被发送回实体,然后该实体应该自行停止。在接收钝化和实体终止之间,分片将缓冲传入消息。此后,此类缓冲的消息被传递到该实体的新化身。