C# 子参与者在失败时不会重新启动
我有一位家长演员:C# 子参与者在失败时不会重新启动,c#,.net,akka,console-application,akka.net,C#,.net,Akka,Console Application,Akka.net,我有一位家长演员: public sealed class PersistenceSupervisor : ReceiveActor { protected override void PreStart() { base.PreStart(); Become(Active); } protected override SupervisorStrategy SupervisorStrategy() { r
public sealed class PersistenceSupervisor : ReceiveActor
{
protected override void PreStart()
{
base.PreStart();
Become(Active);
}
protected override SupervisorStrategy SupervisorStrategy()
{
return new OneForOneStrategy(
10,
TimeSpan.FromSeconds(0),
x =>
{
return Directive.Restart;
});
}
private void Active(object message)
{
IInventorPersister inventorPersistor = new InventorPersister();
IActorRef persister = Context.ActorOf(Props.Create<Persister>(inventorPersistor), "persisterActor");
var task = persister.Ask(message);
task.Wait();
Sender.Tell(task.Result);
}
}
这个想法是重新启动子参与者,直到它成功。但是,当发生故障时,应用程序会立即停止并崩溃。谢谢你的帮助。非常感谢。一些更一般的提示:
ReceiveActor
,它希望在actor的构造函数中通过Receive
/ReceiveAsync
方法提供消息处理程序Been(ActiveAsync)
由非类型化的参与者而不是ReceiveActor继承者使用been
,如果不需要,也不要使用PreStart
方法。在actor初始化期间引发的异常将始终导致actor停止(即使it监管策略是重新启动它)ReceiveAsync
handler
公共密封类持久器:ReceiveActor
{
私有只读inventorPersister inventorPersister;
公共持久器(IIInventorPersister inventorPersister)
{
this.inventorPersister=inventorPersister;
ReceiveAsync(异步消息=>
{
等待持续(消息);
Context.Sender.Tell(“成功”);
});
}
私有异步任务持久化(CreatePublication消息){…}
...
}
谢谢您的帮助,但我没有得到您的答案,因为我想故意抛出一个异常来测试主管策略。我不确定您为什么要测试它。大多数异常的主要原因是重新启动。您可以对其进行测试,但这样您就不会测试您的域,而是测试框架本身。我附上的代码显示了ReceiveActor的配置,因为我怀疑您初始化Actor的方式破坏了它们的内部结构。因为我想确保如果发生任何异常。子参与者将重新启动,直到成功从数据库获取数据。此外,异常不是来自构造函数,而是来自函数RandomFailure.Fail()
。我已经尝试了你的代码,但它不起作用(引发异常并使应用程序崩溃)1。在无限循环中尝试从数据库获取数据是没有意义的,除非烧掉应用程序服务器。2.我展示的代码片段仍然允许您测试代码以进行演员重试,这是设计演员行为的实际方法。
public sealed class Persister : ReceiveActor
{
private readonly IInventorPersister inventorPersister;
protected override void PreStart()
{
base.PreStart();
Become(ActiveAsync);
}
private async void ActiveAsync(object message)
{
try
{
var savedSender = Context.Sender;
Task persisting = Persist(message as CreatePublication);
await persisting;
savedSender.Tell("Success");
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
}
public Persister(IInventorPersister inventorPersister)
{
this.inventorPersister = inventorPersister;
}
private async Task Persist(CreatePublication message)
{
RandomFailure.Fail();
// This function is to make an UPDATE query to db
await inventorPersister.Persist(message.PublicationNumber, message.Inventors);
}
// Random failure for testing purpose
private static class RandomFailure
{
private static readonly Random R = new Random();
public static void Fail()
{
if (R.Next(0, 2) == 0)
{
throw new InvalidOperationException("Random failure");
}
}
}
}