scala cats IOApp 应如何获取 ExecutionContext?

Joe*_*e K 2 scala scala-cats cats-effect

我最近将我的应用程序转换为继承猫的应用程序,如此IOApp所述。我在该文档中读到:

\n\n
\n

Timer[IO] 依赖项已由 IOApp 提供,因此在 JVM 之上,\xe2\x80\x99 不再需要隐式 ExecutionContext 位于范围内

\n
\n\n

但是,我正在与其他几个确实需要ExecutionContext. 是否有推荐的方式来获取此类应用程序?老好人import scala.concurrent.ExecutionContext.Implicits.global对所提供的东西玩得好吗Timer[IO]

\n

Dmy*_*tin 6

尝试扩展特质IOApp.WithContext。对于全球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)
  }
}
Run Code Online (Sandbox Code Playgroud)

或者ExecutionContext来自具有固定线程数的线程池

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
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 请注意,如果您在“run”中调用“executionContextResource.use”,它将被分配两次(一次由 IOApp 本身分配 - 用于实例化您的 Timer 和 ContextShift,另一次由您分配)。为了避免分配两个 EC,请使用 `executionContext` 方法 - 它应该为您提供与 Timer 和 ContextShift 正在使用的相同的 EC(仅在 IOApp.WithContext 中可用) (3认同)