akka.net actor并行执行

时间:2016-12-15 10:24:26

标签: akka.net

我们正在akka.net上进行POC来处理json文件。我正在努力采用批处理JArray的最佳方法。在我的实现中,akka协调器actor收到以下消息:

//coordinator actor receive
public class ValidatedInput
{
public JArray Data { get; set; }
}

我的协调员演员可以像下面一样处理完整的JArray但是我很难开始并行演员的数量,每个人都会处理来自JArray的50条记录。

//coordinator actor receives messages and calls transform actor to process
public void Receiving()
{
Receive<ValidatedInput>(x =>
{
TransformerRouter.Tell(x);
});
}

//transform actor receives message and process, sample code
Receive<ValidatedInput>(x =>
{
PipeToSupport.PipeTo<TransformResult>(MapDataAsync(x).ContinueWith(data =>
{
return new TransformResult();}), Self);
});

有没有像下面这样的方法,我可以传递50个JArray记录,由每个演员处理并收集结果,如:

Receive<ValidatedInputDataResult>(
{
TransformerRouter.Tell(x.Data.Take(50);
});

1 个答案:

答案 0 :(得分:3)

Haven在一段时间内没有使用Akka.NET,但是当我这样做时,我总是避免在可能的情况下绕过收藏品,主要有两个原因:

  • 您可以向演员发送的邮件大小有限制,虽然此限制可以增加this isn't recommended

  • 发送给演员的所有邮件都会被序列化,然后在Receive<>时被反序列化,这意味着如果您要在邮件中发送数组或其他对象集合,则存在风险每次使用Tell方法时都将它们分配给大对象堆,如果这是一个热门代码路径,这应该尽可能地避免。

当时我解决这类问题的方式是:

  • 有一个&#34;顶级&#34;协调员演员:
    • 包含工作者所在的路由器。例如,您可以将路由器配置为distribute messages in a round-robin fashion
    • 产生一个&#34;聚合器&#34;每次新消息Receive时都会有演员,工作人员会将结果发送给他们。您可以使用Tell方法并传递聚合器的actor引用,以便worker在其actor上下文中将聚合器视为Sender
  • &#34;顶级&#34;中的路由器actor被配置为automatically spawn more actors when needed
  • 工作人员只发送Receive条消息,处理它,然后Tell将其发送到其上下文中的Sender

请记住,这个建议可能不完整,因为我不是很流利&#34;在当时使用演员系统,我还没有积极地使用Akka.NET大约6个月,并且可能有更好的方法来完成你需要的东西。

我建议在Google上搜索&#34;演员系统模式&#34;和#34; Scala演员模式&#34;,并阅读一些开源的Scala项目源代码,这也将为您提供一些见解。

最后,提示避免将来头痛:消息类型总是是不可变的。所以你的ValidatedInput应该是这样的:

public class ValidatedInput
{
    public readonly JArray Data { get; }

    public ValidatedInput(JArray data)
    {
        Data = data;
    }
}

或者更好:

public class ValidatedInput
{
    public readonly IReadOnlyList<JToken> Data { get; }

    public ValidatedInput(IReadOnlyList<JToken> data)
    {
        Data = data;
    }
}

希望这有帮助,祝你好运!