当我们有一些需要以原子方式处理的项目时,我仍然在掌握Akka流概念并试图了解如何将它们映射到场景。假设我们有一个由多个项目组成的采购订单,我们需要对每个项目应用一些处理,然后将它们合并回一个值。这样的工作流程是否应该成为自己独立的流(或子流),一旦采购订单被完全处理,该流将被关闭?即每个采购订单都会启动一个新流?或者我有一系列永不停止的采购订单?但如果是这样,我不会有混合不同订单的采购订单的问题吗?
换句话说,我想要实现的是处理不同工作流程的隔离,并想知道Akka流是否提供了良好匹配。
答案 0 :(得分:2)
直接回答您的问题:可以创建一个流,“将一些处理应用于每个项目,然后将它们合并回一个值”。
使用示例代码开发示例:
case class Item(itemId : String)
case class PurchaseOrder(orderId : String, items : Seq[Item])
val purchaseOrder : PurschaseOrder = ???
如果我们想用流来处理项目,虽然减少的确切性质在问题上是模棱两可的,所以我不会定义如何实现折叠:
type ProcessOutput = ???
def processItem(item : Item) : ProcessOutput = ???
val combinedResult : Future[CombinedResult] =
Source.fromIterator( purchaseOrder.items.toIterator )
.via(Flow[Item] map processItem)
.to(Sink.fold[ProcessOutput](???)(???) )
.run()
间接回答你的问题,
考虑期货优先
当需要背压时,Akka流非常有用。当您连接到外部数据源时,背压很常见,因为bp允许您的应用程序确定数据流传输到您的速度,因为您负责不断发出更多数据需求的信号。
如果您在问题中提出,则无需广播需求,and incur the inherent overhead此类通信需要。您已经拥有了一系列商品,因此没有人向...发送需求。
相反,我认为期货是您描述的案例的最佳方式:
def futProcess(item : Item)(implicit ec : ExecutionContext) =
Future { processItem(item) }
// same output type as the stream run
val combinedResults : Future[CombinedResult] =
Future.sequence{ purchaseOrder.items map futProcess }
.map{ _ fold[ProcessOutput](???)(???) }
你可以获得更好的性能,减少拥有完整ActorSystem的复杂性,以及与流完全相同的结果......