异步"节点"在scalaz流中

时间:2015-08-11 09:29:08

标签: scalaz-stream

我有Process[Task, A],我需要运行一个函数A => B,其运行时间在流的每个A上从瞬时到非常长,以产生Process[Task, B] }。

问题在于,我希望尽快在A中处理每个ExecutionContext,并尽快通过结果,无论其顺序如何收到了A

一个具体的例子是下面的代码,我希望所有奇数都能立即打印出来,偶数打印出来的时间大约是500ms。相反,会发生(奇数,偶数)耦合打印,交错持续500ms:

import java.util.concurrent.{TimeUnit, Executors}
import scala.concurrent.ExecutionContext

import scalaz.stream._
import scalaz.concurrent.Task

object Test extends App {
  val executor = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(8))

  Process.range(0, 100).flatMap { i =>
    Process.eval(Task.apply {
      if(i % 2 == 0) Thread.sleep(500)
      i
    }(executor))
  }.to(io.printStreamSink(System.out)(_ println _))
  .run.run

  executor.shutdown()
  executor.awaitTermination(10, TimeUnit.MINUTES)
}

1 个答案:

答案 0 :(得分:1)

原来答案是使用频道。这里的更新代码似乎完全符合我的要求:

import java.util.concurrent.{TimeUnit, Executors}
import scala.concurrent.ExecutionContext

import scalaz.stream._
import scalaz.concurrent.Task

object Test extends App {
  val executor = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(8))
  val chan = channel.lift[Task, Int, Int] { i => Task {
    if(i % 2 == 0) Thread.sleep(500)
    i
  }}

  merge.mergeN(8)(Process.range(0, 100).zipWith(chan)((i, f) => Process.eval(f(i))))
    .to(io.printStreamSink(System.out)(_ println _)).run.run

  executor.shutdown()
  executor.awaitTermination(10, TimeUnit.MINUTES)
}