我目前正在研究一个使用AKKA流1.0处理数据的简单批处理。 如果我避免在流程步骤中使用mapAsync方法,则一切运行顺利。
调用on complete时,结果文件最终确定,代理系统通过Reaper actor关闭(参见Reaper模式):
val file = new File(inputFile)
val run: Future[Int] = source(file)
.via(parse)
.via(enrich)
.via(writeEnriched)
.runWith(printProgress)
run.onComplete { result: Try[Int] =>
context.system.log.info(s"Nb elements processed: ${result.get}")
writerActorRef ! FinalizeResults()
}
我想加速的步骤之一是丰富数据的部分。有时,数据无法丰富,下一步应该被忽略。
def enrich(implicit ec: ExecutionContext) : Flow[Data, EnrichedData, Unit]
= Flow[Data].map(enriched.enrich(_)).collect {
case Some(enrichedData) => enrichedData
}
所有这些代码运行良好,并且在调用onComplete()时我没有丢失元素。
Input: 45639
Nb elements processed: 45639
当我尝试使用mapAync和Future而不是map for enrichment步骤加速时,在处理完所有元素之前调用onComplete。
def enrich(implicit ec: ExecutionContext) : Flow[Data, EnrichedData, Unit]
= Flow[Data].mapAsyncUnordered(8)(data => Future(enricher.enrich(data))).collect {
case Some(enrichedData) => enrichedData
}
我最后错过了一些元素而且从来没有相同的数字 所有这些代码都运行良好,并且在调用onComplete()时我没有丢失元素。
Input: 45639
Nb elements processed: 45628
我无法找到一种方法来发现所有内容都已处理完毕...... 知道我做错了吗?
答案 0 :(得分:2)
最后我发现了这个问题。我的问题不是在akka流上,而是在一个非线程安全的限制检查器上....感谢您的帮助 对于那些感兴趣的人,我已经在github上传了一些代码:https://github.com/PixelDuck/akka-stream-test