我有一个父演员:
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);
}
}
并且具有随机失败功能的儿童演员用于测试目的:
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");
}
}
}
}
这个想法是重新启动子actor,直到它成功为止。但是,当故障发生时,应用程序会在那里停止并崩溃。我感谢任何帮助。非常感谢你。
答案 0 :(得分:1)
一些更一般的提示:
ReceiveActor
期望在actor的构造函数中通过Receive
/ ReceiveAsync
方法提供消息处理程序。非类型化actor使用Become(ActiveAsync)
而不是ReceiveActor继承者。Become
方法中使用PreStart
。在actor初始化期间抛出的异常将导致actor被停止(即使监督策略是重启它)。话虽这么说,最简单的方法就是为你的演员提供ReceiveAsync
处理程序。
public sealed class Persister : ReceiveActor
{
private readonly IInventorPersister inventorPersister;
public Persister(IInventorPersister inventorPersister)
{
this.inventorPersister = inventorPersister;
ReceiveAsync<CreatePublication>(async message =>
{
await Persist(message);
Context.Sender.Tell("Success");
});
}
private async Task Persist(CreatePublication message) { ... }
...
}