如何组合多个Scalaz-Streams,以便保留完成顺序但不强制执行交错?

时间:2014-02-19 18:57:00

标签: stream scalaz tee scalaz-stream

var num =0
var num2 = 3333
val p2 = Process.eval {
  Thread.sleep(10000)
  Task.delay {
    Thread.sleep(10000)
    num2 = num2 + 1
    s"hi ${num2}"
  }
}.repeat.take(15)

//p2: scalaz.stream.Process[[x]scalaz.concurrent.Task[x],String] =
// Await(scalaz.concurrent.Task@5a554f1c,
//<function1>,Halt(scalaz.stream.Process$End$),Halt(scalaz.stream.Process$End$))

val p1 = Process.eval {
  Thread.sleep(2000)
  Task.delay { 
    Thread.sleep(2000)
    num = num + 1
    s"hi $num"
  }
}.repeat.take(15)

//p1: scalaz.stream.Process[[x]scalaz.concurrent.Task[x],String] = 
// Await(scalaz.concurrent.Task@7a54e904,
// <function1>,Halt(scalaz.stream.Process$End$),Halt(scalaz.stream.Process$End$))

// this interleaves them and I get disjunctions showing me their order
(p1 either p2).map(println).run.run

// this gives me the strings that are interleaved
(p1 interleave p2).map(println).run.run

你如何得到一个过程,它是两个过程的组合,但只是它们到达的顺序(意味着如果左边在右边前两次,那没关系,给左边两次,然后当右边到达时发出它然后)?

我正在寻找一个睡眠时间更短的人,并且在较慢的过程之前看到它多次出现。提前感谢任何花时间阅读本文的人,尤其是那些可以分享一些见解的人。

1 个答案:

答案 0 :(得分:4)

埃里克,

非确定性交织通过Process.wye在scalaz-stream中实现,实际上要么是使用Yye的非确定性组合器之一。你看到它们左/右交错的原因是因为它试图公平并因为你阻塞线程。尝试创建比第二个更慢的一侧,您将看到其中一个是非确定性的。

注意为了实现非确定性行为,您需要实际上从两个线程运行的进程,您的p1进程实际上阻塞了单个线程,因此在您的方案中,顺序始终是确定的

尝试:

val p1 = Process(1,2,3).toSource
val p2 = Process(10) fby Process.sleep(1 second) fby Process(20,30).toSource

(p1 either p2).runLog.run.foreach(println)

那应该发出

-\/(1)
\/-(10)
-\/(2)
-\/(3)
\/-(20)
\/-(30)