Skip to content

Instantly share code, notes, and snippets.

@LGLO
Created July 1, 2018 20:36
Show Gist options
  • Select an option

  • Save LGLO/c53a127d24dfee66b094749262ba0fec to your computer and use it in GitHub Desktop.

Select an option

Save LGLO/c53a127d24dfee66b094749262ba0fec to your computer and use it in GitHub Desktop.
Ping app with Scalaz8 ZIO
import java.io.IOException
import scalaz.zio.console.putStrLn
import scalaz.zio.{IO, IOApp, IOQueue, Void}
import scala.concurrent.duration.Duration
sealed trait PongMessages
case class Ping(n: Int) extends PongMessages
case object Stop extends PongMessages
sealed trait PingMessages
case class Pong(n: Int) extends PingMessages
object PingPong extends IOApp {
// Ping process, sends `Ping` messages to `pong`s inbox and awaits `Pong`.
// Trampolines for next execution.
def ping(
inbox: IOQueue[PingMessages],
pong: IOQueue[PongMessages],
pingsToSend: Int
): IO[IOException, Unit] = pingsToSend match {
case 0 => pong.offer(Stop)
case n =>
for {
_ <- pong.offer(Ping(n)).delay(Duration("1 ms"))
msg <- inbox.take
_ <- putStrLn(s"Ping received: $msg")
go <- ping(inbox, pong, n - 1)
} yield go
}
// Pong process, awaits `Ping` and replies with `Pong`.
// Trampolines for next execution unless `Stop` is received.
def pong(
inbox: IOQueue[PongMessages],
ping: IOQueue[PingMessages]
): IO[IOException, Unit] = for {
msg <- inbox.take
_ <- putStrLn(s"Pong received: $msg")
recurse <- msg match {
case Ping(n) => ping.offer(Pong(n)).flatMap(_ => pong(inbox, ping))
case Stop => IO.now[IOException, Unit](())
}
} yield recurse
def run(args: List[String]): IO[Void, ExitStatus] = {
for {
pingQueue <- IOQueue.make[IOException, PingMessages](1)
pongQueue <- IOQueue.make[IOException, PongMessages](1)
_ <- ping(pingQueue, pongQueue, 30000).fork // fire-and-forget
_ <- pong(pongQueue, pingQueue) // requires completion of `pong`
} yield ()
}.attempt.map(_.fold(_ => 1, _ => 0)).map(ExitStatus.ExitNow(_))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment