Skip to content

Instantly share code, notes, and snippets.

@ChristopherDavenport
Last active May 11, 2021 23:41
Show Gist options
  • Save ChristopherDavenport/d41f60ae7ef2801421931c0023e86434 to your computer and use it in GitHub Desktop.
Save ChristopherDavenport/d41f60ae7ef2801421931c0023e86434 to your computer and use it in GitHub Desktop.
Exercise on clean shutdown
import cats._
import cats.syntax.all._
import cats.effect._
import cats.effect.syntax.all._
import org.http4s._
import org.http4s.implicits._
import org.http4s.ember.server._
import scala.concurrent.duration._
object Main extends IOApp {
def run(args: List[String]): IO[ExitCode] = {
for {
foo <- DoFoo.impl[IO]
_ <- EmberServerBuilder.default[IO].withHttpApp(Routes.routes(foo).orNotFound).build
} yield ()
}.use(_ => IO.never)
}
object Routes {
def routes[F[_]: Sync](doFoo: DoFoo[F]) = HttpRoutes.of[F]{
case _ => doFoo.foo(Foo()).as(Response(Status.Accepted))
}
}
case class Foo()
trait DoFoo[F[_]]{
def foo(f: Foo): F[Unit]
}
object DoFoo {
def impl[F[_]: Concurrent: Timer]: Resource[F, DoFoo[F]] = for {
queue <- Resource.liftF(fs2.concurrent.Queue.noneTerminated[F, Foo])
_ <- queue
.dequeue
.evalMap(foo => Timer[F].sleep(10.seconds) >> Concurrent[F].delay(println(foo)))
.compile
.drain
.background
_ <- Resource.make(Applicative[F].unit)(_ => queue.enqueue1(None))
} yield new DoFoo[F]{
def foo(f: Foo): F[Unit] = queue.enqueue1(f.some)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment