我正在PlayFramework中构建一个应用程序,它必须进行一些密集的文件解析,最好是并行的。用户上传一个解压的存档,文件存储在驱动器上。在这个存档中有一个文件(我们称之为main.csv
),它有多个列。(如subPage1.csv
)。此列可以为空,以便main.csv
中并非所有行都有子页。
现在,我启动一个Akka Actor来解析主.csv文件。
public MainParser extends ActorRef {
@Inject
@Named("subPageParser")
private AcgtorRef subPageParser;
public Receive createReceive() {
...
if (column[3] != null) {
subPageParser.tell(column[3], getSelf());
}
}
}
子页面解析器属性:
public static Props getProps(JPAApi jpaApi) {
return new RoundRobinPool(3).props(Props.create((Class<?>) SubPageParser.class, jpaApi));
}
现在,我的问题是,考虑到一个subPage可能需要5秒钟来解析,我将使用SubPageParser
的单个示例,还是将有多个并行处理的示例。
另外,考虑另一个场景,其中名称存储在DB中,我使用如下代码:
List<String> names = dao.getNames();
for (String name: names) {
subPageParser.tell(name, null);
}
在这种情况下,考虑到subPageParser
ActorRef是像以前一样使用Guice @Inject获得的,我是否要进行并行处理?
如果我正在并行处理,我如何控制正在生成的Actors的数量?如果我有1000个子页面,我不希望有1000个Actors。而且,它们的寿命可能是一个问题。
**注意:**我有一个类似这样的ActorsModule,所以我可以使用@Inject而不是Props:
public class ActorsModule extends AbstractModule implements AkkaGuiceSupport {
@Override
protected void configure() {
bindActor(MainParser.class, "mainparser");
Function<Props, Props> props = p -> SubPageParser.getProps();
bindActor(SubPageParser.class, "subPageParser", props);
}
}
UPDATE:我已经修改为使用一个RoundRobinPool。但是,这并不像预期的那样工作。我指定了3作为示例的数量,但是我在if中为每个解析请求获得了一个新的对象。
1条答案
按热度按时间wvt8vs2t1#
像您这样注入一个参与者将导致每个
MainParser
有一个SubPageParser
。虽然您可能向它发送1000条消息(使用tell
),但它们将被逐个处理,而其他消息则在邮箱中等待处理。对于您的设计,您需要注意,注入这样的参与者将创建另一个顶级参与者,而不是将
SubPageParser
创建为子参与者,这将允许父参与者控制和监视它。playframework支持注入子参与者,如其文档中所述:https://www.playframework.com/documentation/2.6.x/JavaAkka#Dependency-injecting-child-actors虽然您可以让akka使用一定数量的子actors来分配负载,但我认为您首先应该质疑为什么要使用actors。大多数问题都可以通过简单的
Future
来解决。例如,您可以配置一个自定义线程池来运行您的Future
,并让它们在您希望的并行化级别上完成工作:https://www.playframework.com/documentation/2.6.x/ThreadPools#Using-other-thread-pools