Кластер 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.