如何在Cats Effect IO模式中使用弹簧数据CrudRepository?存储库方法是否保存线程阻塞?

时间:2019-04-28 08:11:55

标签: scala spring-data-jpa cats-effect

我必须与userRepository.save(User(1, "test"))合作才能理解IO。 我认为它正在阻止线程操作,并尝试ContextShift.evalOn正确编写代码(https://typelevel.org/cats-effect/concurrency/basics.html#blocking-threads

  implicit val contextShift: ContextShift[IO] = IO.contextShift(ExecutionContext.global)
  val blockingEC                              = ExecutionContext.fromExecutor(Executors.newCachedThreadPool())

  def doSth(str: String): IO[Unit]      = IO(println(str))
  def blockingOp(str: String): IO[Unit] = IO(userRepository.save(User(1, str)))

  def greeting(msg: String): IO[Unit] =
    for {
      _ <- doSth("Before blocking operation.")
      _ <- contextShift.evalOn(blockingEC)(blockingOp("testName"))
      _ <- doSth("After blocking operation")
    } yield ()

  val run = greeting("test").unsafeRunAsyncAndForget()

在此示例中使用了ExecutionContext.global,如何避免呢? 以及如何使用(https://monix.io/docs/3x/best-practices/blocking.html)中的monix。 我尝试了下一个,但是未执行保存操作。

  private val io = Scheduler.io(name = "engine-io")

  def executeBlockingIO[T](cb: => T): Future[T] = {
    val p = Promise[T]()

    io.execute(new Runnable {
      def run() =
        try {
          p.success(cb)
        } catch {
          case NonFatal(ex) =>
            logger.error(s"Uncaught I/O exception", ex)
            p.failure(ex)
        }
    })
    p.future
  }

  def doSth(str: String): IO[Unit]      = IO(println(str))
  def blockingOp(str: String): IO[Unit] = IO(userRepository.save(User(1, str)))

  def greeting(msg: String): IO[Unit] =
    for {
      _ <- doSth("Before blocking operation.")
      _ <- IO.fromFuture(IO(executeBlockingIO(blockingOp("testName"))))
      _ <- doSth("After blocking operation")
    } yield ()

  val test = greeting("test").unsafeRunAsyncAndForget()

0 个答案:

没有答案