Search code examples
scalascala-catscats-effect

How should a scala cats IOApp acquire an ExecutionContext?


I've recently converted my app to inheriting cats's IOApp as described here. I read in that documentation:

the Timer[IO] dependency is already provided by IOApp, so on top of the JVM there’s no longer a need for an implicit ExecutionContext to be in scope

However, I'm interacting with several other libraries (i.e. http4s) that do require an ExecutionContext. Is there a recommended way to acquire one in this type of application? Does the good old import scala.concurrent.ExecutionContext.Implicits.global play nice with that provided Timer[IO]?


Solution

  • Try extending trait IOApp.WithContext. For global ExecutionContext

    import cats.effect._
    import scala.concurrent.ExecutionContext
    
    object Main extends IOApp.WithContext {
      implicit val ec = ExecutionContext.global
    
      override protected def executionContextResource: Resource[SyncIO, ExecutionContext] =
        Resource.liftF(SyncIO(ec))
    
      def run(args: List[String]): IO[ExitCode] = {
    
        implicitly[Timer[IO]]
        implicitly[ContextShift[IO]]
        implicitly[ExecutionContext]
    
        IO.pure(ExitCode.Success)
      }
    }
    

    or for ExecutionContext from a thread pool with fixed number of threads

    import java.util.concurrent.{Executors, TimeUnit}
    import cats.effect._
    import scala.concurrent.ExecutionContext
    
    object Main extends IOApp.WithContext {
      override protected def executionContextResource: Resource[SyncIO, ExecutionContext] =
        Resource.make(SyncIO(Executors.newFixedThreadPool(8)))(pool => SyncIO {
          pool.shutdown()
          pool.awaitTermination(10, TimeUnit.SECONDS)
        }).map(ExecutionContext.fromExecutorService)
    
      def run(args: List[String]): IO[ExitCode] = {
        executionContextResource.use { implicit ec =>
    
          implicitly[Timer[IO]]
          implicitly[ContextShift[IO]]
          implicitly[ExecutionContext]
    
          SyncIO.pure(ExitCode.Success)
        }.toIO
      }
    }
    

    https://github.com/typelevel/cats-effect/issues/337

    https://github.com/typelevel/cats-effect/pull/344