2016-12-15 48 views
2

我们正在akka.net上处理json文件的POC。我正在努力处理批量处理JArray的最佳方法。我在执行阿卡协调演员收到以下消息:akka.net演员并行执行

//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); 
}); 

回答

3

没有使用Akka.NET在一段时间,但是当我做,我总是避免绕过集合在可能的情况,主要有两个原因:

  • 上有邮件大小,您可以发送到演员的限制,虽然这种限制可以增加了this isn't recommended

  • 发送到演员的消息都是系列化,然后当Receive<>倒是反序列化,这意味着如果你在一个消息发送对象的数组或其他收藏品,你的风险让他们在每一次大对象堆分配你使用Tell方法,如果这是一个热门的代码路径,应该尽可能避免这种方法。

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

  • 有一个“顶级”协调员演员说:
    • 包含路由器后面,其工人的演员是。例如,您可以将路由器配置为distribute messages in a round-robin fashion
    • 每当新消息Receive'd产生一个“聚合器”演员时,工作者演员将向其发送结果。您可以使用Tell方法并传递聚合器的参与者参考,以便工作人员在其参与者上下文中将聚合器视为Sender
  • 在“顶级”演员的路由器配置为automatically spawn more actors when needed
  • 工人的演员做无非Receive多单的消息,流程,然后将其Tell在其上下文Sender

请记住,这个建议可能并不完整,因为当时我不太“流利”地使用演员系统,而且我还没有积极使用Akka.NET大约6个月,成为你需要的更好的方法。

我建议在谷歌搜索“演员系统模式”和“斯卡拉演员模式”,并阅读一些开源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; 
    } 
} 

希望这有助于和好运!