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]
?
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
}
}