Created
July 1, 2018 20:36
-
-
Save LGLO/c53a127d24dfee66b094749262ba0fec to your computer and use it in GitHub Desktop.
Ping app with Scalaz8 ZIO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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