Skip to content

Instantly share code, notes, and snippets.

@guizmaii
Forked from fanf/ZioExecSemantic.scala
Created April 22, 2019 21:00
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 guizmaii/689ed7c18241d6e7c7197a87a3c7e6ac to your computer and use it in GitHub Desktop.
Save guizmaii/689ed7c18241d6e7c7197a87a3c7e6ac to your computer and use it in GitHub Desktop.
Show how ZIO behave with/without fiber fork.
/*
* This test shows that without a fork, execution is purely mono-fiber and sequential.
*/
object TestZioExecSemantic {
val rt = new DefaultRuntime {}
trait LOG {
def apply(s: String): UIO[Unit]
}
def makeLog = UIO(new LOG {
val zero = System.currentTimeMillis()
def apply(s : String) = UIO(println(s"[${System.currentTimeMillis()-zero}] $s"))
})
val semaphore = Semaphore.make(1)
// prog 1 has no 'fork'
def prog1(c: Clock) = for {
sem <- semaphore
log <- makeLog
_ <- log("sem get 1")
a <- sem.withPermit(IO.effect(println("Hello world 1")))
_ <- log("sem get 2")
b <- sem.withPermit(IO.effect({println("sleeping now"); Thread.sleep(2000); println("after sleep: second hello")}))
_ <- log("sem get 3")
// at tham point, the semaphore is free because b is fully executed, so no timeout
c <- sem.withPermit(IO.effect(println("third hello"))).timeout(Duration(5, java.util.concurrent.TimeUnit.MILLISECONDS)).provide(c)
_ <- c match {
case None => log("---- A timeout happened")
case Some(y) => log("++++ No timeout")
}
} yield ()
// prog 2 uses 'fork'
def prog2(c: Clock) = for {
sem <- semaphore
log <- makeLog
_ <- log("sem get 1")
a <- sem.withPermit(IO.effect(println("Hello world 1"))).fork
_ <- log("sem get 2")
b <- sem.withPermit(IO.effect({println("sleeping now"); Thread.sleep(2000); println("after sleep: second hello")})).fork
_ <- log("sem get 3")
c <- sem.withPermit(IO.effect(println("third hello"))).timeout(Duration(5, java.util.concurrent.TimeUnit.MILLISECONDS)).provide(c).fork
_ <- a.join
_ <- b.join
x <- c.join
_ <- x match {
case None => log("---- A timeout happened")
case Some(y) => log("++++ No timeout")
}
} yield ()
def main(args: Array[String]): Unit = {
rt.unsafeRunSync(prog1(rt.Environment))
println("****************")
rt.unsafeRunSync(prog2(rt.Environment))
/* exec prints:
[2] sem get 1
Hello world 1
[50] sem get 2
sleeping now
after sleep: second hello
[2053] sem get 3
third hello
[2178] ++++ No timeout
****************
[2] sem get 1
Hello world 1
[6] sem get 2
sleeping now
[10] sem get 3
after sleep: second hello
[2015] ---- A timeout happened
Process finished with exit code 0
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment