如何制作akka流源队列FIFO?

时间:2018-05-22 13:40:49

标签: stream akka akka-stream

我正在使用akka开发股票交易系统。 我将订单簿提供给TradeQueue,如下所示:

val tradeQueue = Source.queue[TradeTask](1, OverflowStrategy.backpressure)
.map(task=>{
  println("TradeTask Start:"+task)
  task
})
.via(ProcessA)
.via(ProcessC)
.via(ProcessC)
.toMat(Sink.foreach(task => {
     log.info("TradeTask finish:"+task)
 }))(Keep.left).run()


 for (item <- 1 to 100) {
    val task = TradeTask(item)
    tradeQueue.offer(task)
 }   

但序列无序。

喜欢这样:

TradeTask开始:TradeTask(1)

TradeTask开始:TradeTask(2)

TradeTask完成:TradeTask(1)

TradeTask完成:TradeTask(2)

但我希望FIFO和元素在前一个完成之前排队,就像这样

TradeTask开始:TradeTask(1)

TradeTask完成:TradeTask(1)

TradeTask开始:TradeTask(2)

TradeTask完成:TradeTask(2)

怎么做?感谢

1 个答案:

答案 0 :(得分:1)

已经是一个FIFO

你的问题已经证明队列是“(F)irst(I)n(F)irst(O)ut”。如输出中所示,输入流的第一个元素TradeTask(1)Sink要处理的第一个元素:

TradeTask Start:TradeTask(1)    // <-- FIRST IN

TradeTask Start:TradeTask(2)

TradeTask finish:TradeTask(1)   // <-- FIRST OUT

TradeTask finish:TradeTask(2)

间接答案

您提出的问题与akka-stream的目的/用法完全相反。您正在询问如何创建一个连续执行所有处理的akka​​流,而不是异步处理。

akka的重点是asynchronous processing & communication

  

欢迎来到Akka,这是一套用于设计的开源库   可扩展的弹性系统,跨越处理器核心和网络。

如果您希望一次一个地完成处理,那么为什么一开始就使用akka?使用scala集合和for-comprehensions,很容易实现Iterable元素的同步处理,没有akka:

val functionA : Task => Task = ???
val functionB : Task => Task = ???
val functionC : Task => Task = ???

val logTask : Task => Unit = 
  (task) => log.info("TradeTask finish:" + task)

for {
  item    <- 1 to 100
  task    <- TradeTask(item)
  aResult <- functionA(task)
  bResult <- functionB(aResult)
  cResult <- functionC(bResult)
} { 
  logTask(cResult)
}

同样,您可以使用函数组合和简化迭代:

val compositeFunction : Int => Unit = 
  TradeTask.apply andThen functionA andThen functionB andThen functionC andThen logTask

(1 to 100) foreach compositeFunction