Skip to content

Instantly share code, notes, and snippets.

@dcsobral
Last active August 29, 2015 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dcsobral/61d1e6cfe1324011f616 to your computer and use it in GitHub Desktop.
Save dcsobral/61d1e6cfe1324011f616 to your computer and use it in GitHub Desktop.
import scalaz._
import Scalaz.{merge => _, _}
import scalaz.concurrent._
import scalaz.stream._
import scala.concurrent.duration._
implicit val defaultScheduler = scalaz.stream.DefaultScheduler
val flag = async.signal[Boolean]
val reset = Process.eval(flag set true).drain
val sleep = Process sleep 50.millis
val check = Process eval flag.get
val completeEmitAll = Process.eval(flag set false).drain
val emitAll: Process[Task, Process[Task, Boolean]] = Process(reset, sleep, check) onComplete completeEmitAll
val test = for {
join <- emitAll.join.runLast
mergeN <- merge.mergeN(emitAll).runLast
} yield (join exists identity, mergeN exists identity)
val (join, mergeN) = test.run
assert(join)
assert(mergeN) // fails!
@alissapajer
Copy link

@dcsobral is it the order of the printed output that concerns you, the fact that Completed emitAll prints before the three Completed p*? With an infinite list for ps, do you see the Completed p* printlns?

@djspiewak
Copy link

Here's a slightly more minimal test case for you:

import scalaz.syntax.monad._

val stuff = Process(Process.eval(Task delay { Thread.sleep(200); println("*dances about*") })) onComplete
  Process.eval_(Task delay { println("hey there!") })

stuff.join.run.run
println("moving on...")
merge.mergeN(stuff).run.run

@djspiewak
Copy link

And here's a test case which has reproducible assertions:

import scalaz.concurrent.Task
import scalaz.syntax.monad._

import java.util.concurrent.atomic.AtomicBoolean

val flag = new AtomicBoolean(false)

val stuff = Process(Process.eval(Task delay { Thread.sleep(200); !flag.get() })) onComplete
  Process.eval_(Task delay { flag.set(true) })

val test = for {
  results1 <- stuff.join.runLog

  _ <- Task delay {
    flag.set(false)
  }

  results2 <- merge.mergeN(stuff).runLog
} yield (results1 forall identity, results2 forall identity)

val (results1, results2) = test.run

results1 must beTrue
results2 must beTrue      // fails!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment