Skip to content

Instantly share code, notes, and snippets.

@tkroman
Created June 20, 2019 16:52
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 tkroman/841d4783293a4e4e844d2ffa7a6a3d99 to your computer and use it in GitHub Desktop.
Save tkroman/841d4783293a4e4e844d2ffa7a6a3d99 to your computer and use it in GitHub Desktop.
package com.lotusflare.chmiddleman
import cats.effect.ExitCase.Canceled
import cats.effect.{ ExitCode, IO, IOApp, Resource }
import cats.implicits._
import monix.eval.Task
import monix.execution.Scheduler.Implicits.global
import scala.concurrent.duration._
object Resources extends IOApp {
class Res(name: String) {
def close(): Unit = println(s"Closing $name")
}
case class Env(
r1: Res,
r2: Res,
)
def app(env: Env): Task[Unit] = {
def loop: Task[Unit] = {
(for {
_ <- Task(println("polling..."))
recs <- Task(env.r1) // this is e.g. a connection and I'm fetching some data with it
_ <- Task(println("processing..."))
_ <- Task(recs.hashCode()) // "complicated" processing
_ <- Task(s"Read & processed data")
} yield {
()
}).uncancelable >> Task.sleep(1.second) >> loop
}
loop
.doOnFinish {
case None =>
Task(println("Finished"))
case Some(err) =>
Task(err.printStackTrace()) // disregard, properly logged
}
.doOnCancel(Task(println("Cancelled processing loop")))
.executeWithOptions(_.enableAutoCancelableRunLoops)
}
override def run(args: List[String]): IO[ExitCode] = {
val env: Resource[Task, Env] = for {
cfg <- Resource.make(Task(new Res("cfg")))(r => Task(r.close()))
conn <- Resource.make(Task(new Res(s"conn1($cfg)")))(r => Task(r.close()))
} yield {
Env(cfg, conn)
}
env
.use(env => app(env).as(ExitCode.Success))
.guaranteeCase {
case Canceled =>
Task(println("Cancelled, shutting down"))
case other =>
Task(println(s"Exiting because $other"))
}
.toIO
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment