Skip to content

Instantly share code, notes, and snippets.

@sshark
Last active August 27, 2022 16:18
Show Gist options
  • Save sshark/308f67f4c9f2d7b734bfcf6e24dac55d to your computer and use it in GitHub Desktop.
Save sshark/308f67f4c9f2d7b734bfcf6e24dac55d to your computer and use it in GitHub Desktop.
package org.teckhooi
import cats.effect.{ExitCode, IO, IOApp}
import cats.effect.IO.ioParallel // requires for UptimeService[IO]
import cats.{Id, Monad, Parallel, Show}
import cats.syntax.parallel._
import cats.syntax.functor._
import cats.syntax.traverse._ // requires for traverse
import cats.syntax.show._
import cats.syntax.flatMap._ // requires for UptimeService[Id]
import scala.concurrent.duration.{Duration, SECONDS}
import scala.concurrent.{Await, Future}
object UptimeApp extends IOApp {
trait UptimeClient[F[_]] {
def getUptime(hostname: String): F[Int]
}
class UptimeService[F[_]: Monad: Parallel](implicit client: UptimeClient[F]) {
def getTotalUptime(hostnames: List[String]): F[Int] =
// hostnames.parTraverse(client.getUptime).map(_.sum) // takes 1s to complete
hostnames.traverse(client.getUptime).map(_.sum) // takes 2s to complete
}
val hosts: Map[String, Int] = Map("host1" -> 10, "host2" -> 8)
import concurrent.ExecutionContext.Implicits.global
implicit object FutureClient extends UptimeClient[Future] {
override def getUptime(hostname: String): Future[Int] = {
Thread.sleep(1000)
Future(hosts.getOrElse(hostname, 0))
}
}
implicit object IOClient extends UptimeClient[IO] {
override def getUptime(hostname: String): IO[Int] = {
IO.sleep(Duration(1, SECONDS)) *> IO.pure(hosts.getOrElse(hostname, 0))
}
}
implicit object IdClient extends UptimeClient[Id] {
override def getUptime(hostname: String): Int = hosts.getOrElse(hostname, 0)
}
implicit def showFuture[A: Show]: Show[Future[A]] =
(t: Future[A]) => Await.result(t, Duration(1, SECONDS)).show
override def run(args: List[String]): IO[ExitCode] = {
for {
startMillis <- IO(System.currentTimeMillis())
service = new UptimeService[IO]
result <- service.getTotalUptime(List("host1", "host2"))
_ <- IO(println(s"Result: $result"))
_ <- IO(println(s"Time taken: ${System.currentTimeMillis() - startMillis}ms"))
} yield ExitCode.Success
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment