Akka.net 重新启动隔离节点上的执行元系统终止

x33g5p2x  于 2022-11-05  发布在  .NET
关注(0)|答案(1)|浏览(151)

我们正在使用www.example.comv1.4.38开发一个集群Akka.net,我们拥有使用Akka.IO.TCP与外部系统进行通信的种子节点,和多个客户端节点,这些客户端节点接收消息并向种子节点发送消息。如果客户端节点与群集失去通信,则需要在此节点上重新启动Akka actor系统,因为它已被隔离。我们创建了一个执行元,用于侦听AssociationErrorEvent和ThisActorSystemQuarantinedEvent,并在收到这些消息时重新启动系统。

public class ErrorManagerActor: ReceiveActor {
    public ErrorManagerActor(Action action) {
        Receive<ThisActorSystemQuarantinedEvent>(m => {
            action();
        });
        Receive<AssociationErrorEvent>(m => {
            action();
        });
    }
}

问题是,actor系统从不停止并在控制台中显示警告:
[CoordinatedShutdown(akka://xxxxx)]协调关机阶段[actor-system-terminate]在00:00:10之后超时
我们创建了一个UnitTest来重现该问题。

[Test]
    public void TerminateSystemTest() {
        var actor = Sys.ActorOf(Props.Create<ErrorManagerActor>(() => {
            if (!Sys.Terminate().Wait(10000))
                Assert.Fail("Unable to terminate actor system");
            terminatedEvent.Set();
        }));
        Sys.EventStream.Subscribe(actor, typeof(AssociationErrorEvent));
        Sys.EventStream.Subscribe(actor, typeof(ThisActorSystemQuarantinedEvent));
        var cluster = Cluster.Get(Sys);
        Sys.EventStream.Publish(new ThisActorSystemQuarantinedEvent(cluster.SelfAddress, cluster.SelfAddress));
        terminatedEvent.WaitOne();
    }
vxqlmq5t

vxqlmq5t1#

您的测试失败的原因是,为了终止ActorSystem,必须首先终止所有参与者,* 包括 * 运行您的测试Assert的参与者。因此,让参与者在System.Terminate上执行阻塞Task.Wait将导致死锁。
要在生产系统中解决此问题,请 * 不要等待 * Task

相关问题