Кластер Akka.NET node изящное закрытие

У меня есть кластер Akka.NET, содержащий семя Маяка node и два других узла, на которых действуют актерские системы. Когда я пытаюсь сделать изящное завершение работы на одном из моих узлов кластера, я хочу видеть, что хотя бы один из других узлов видит сообщение об уходе node и что все узлы кластера в конечном итоге исключают уход node список узлов.

После того, как я позаботился о том, что я ожидаю, что мне удастся отключить систему актеров, если два других узла не сойдут с ума по поводу невозможности подключиться к node, который выключится...

Теперь у меня есть консольное приложение, заключенное в приложение TopShelf:

class ActorService : ServiceControl
{
    private ActorSystem _actorSystem;

    public bool Start(HostControl hostControl)
    {
        _actorSystem = ActorSystem.Create("myActorSystem");

        var cluster = Cluster.Get(_actorSystem);
        cluster.RegisterOnMemberRemoved(_Terminate);

        return true;
    }

    public bool Stop(HostControl hostControl)
    {
        var cluster = Cluster.Get(_actorSystem);
        cluster.Leave(cluster.SelfAddress);
        return true;
    }

    private void _Terminate()
    {
        _actorSystem.Terminate();
    }
}

Вот моя главная:

class Program
{
    static int Main(string[] args)
    {
        return (int) HostFactory.Run(x =>
        {
            x.UseAssemblyInfoForServiceInfo();
            x.RunAsLocalSystem();
            x.StartAutomatically();
            x.Service<ActorService>();
            x.EnableServiceRecovery(r => r.RestartService(1));
        });
    }
}

Когда вы переходите через функцию "Стоп", я не вижу ни одного принятого сообщения о node, оставшегося на других узлах. Однако, когда функция возвращает, другие узлы начинают исключать извержения.

Пользователь в канале Gitter Akka.NET сказал:

Я наблюдал то же самое даже без TopShelf, я должен сказать, с чистым Проект ASP.NET Core после завершения веб-хостинга.

Ответ 1

Я думаю, проблема в том, что метод Stop() завершается до завершения завершения. Вы должны дождаться события MemberRemoved.

Этот метод Stop() будет ждать, пока вызван обратный вызов MemberRemoved, и сообщит, что он даже остановил систему актеров.

class Worker
{
    private static readonly ManualResetEvent asTerminatedEvent = new ManualResetEvent(false);
    private ActorSystem actorSystem;

    public void Start()
    {
        this.actorSystem = ActorSystem.Create("sample");
    }

    public void Stop()
    {
        var cluster = Akka.Cluster.Cluster.Get(actorSystem);
        cluster.RegisterOnMemberRemoved(() => MemberRemoved(actorSystem));
        cluster.Leave(cluster.SelfAddress);

        asTerminatedEvent.WaitOne();
        //log.Info("Actor system terminated, exiting");
    }

    private async void MemberRemoved(ActorSystem actorSystem)
    {
        await actorSystem.Terminate();
        asTerminatedEvent.Set();
    }

}

Примечание. Я проверил три типа приложений, как оставить кластер без проблем. Я разместил это на GitHub. Есть все еще некоторые исключения и несколько мертвых букв при выходе, но другие узлы больше не пытаются постоянно подключаться к выходу node.