Scala 理解与取消相关的cats.effect.Concurrent
鉴于: build.sbt src/main/scala/net/main.scala 注意,大约30秒后,我取消了它 为什么Scala 理解与取消相关的cats.effect.Concurrent,scala,cats-effect,Scala,Cats Effect,鉴于: build.sbt src/main/scala/net/main.scala 注意,大约30秒后,我取消了它 为什么“秒数已完成:未打印: notUncancellable seconds begin: 303055 ^C$ ?不可取消我相信是不言自明的 在《不可癌变》中,你会遇到类似的情况 正如Alexandru Nedelcu所说: fiber.cancel使fiber.join在IO情况下不终止。因此fiber.join将永远不会完成,并且该保证永远不会得到评估的机会 如果你也
“秒数已完成:
未打印:
notUncancellable
seconds begin: 303055
^C$
?
不可取消
我相信是不言自明的
在《不可癌变》中,你会遇到类似的情况
正如Alexandru Nedelcu所说:
fiber.cancel
使fiber.join
在IO情况下不终止。因此fiber.join
将永远不会完成,并且该保证永远不会得到评估的机会
如果你也取消了评估,你可以强制进行评估。在真正的应用程序中,如果你关心fiber.join的结果,你需要这样做
据我所知,这是一种可能的解释
取消的光纤无法返回成功的值-这是显而易见的。但如果它返回另一个故障的异常…它还将返回一个值,该值可以被视为由光纤计算的值-该值不应返回任何值,因为它已被取消
因此,在这种情况下,整个线程都在等待一个从未到达的值
为了避免这样的陷阱,你可以使用一些不太“低级”的东西,比如racePair
或类似的东西来避免自己处理这样的问题。你可以阅读Oleg Pyzhcov的一篇短文
package net
import cats.effect._
import cats.implicits._
import java.util.concurrent.TimeUnit
import scala.concurrent.duration._
object App extends IOApp { self: IOApp =>
override def run(args: List[String]): IO[ExitCode] =
for {
_ <- uncancellable
_ <- notUncancellable
} yield ExitCode.Success
private def uncancellable: IO[Unit] = {
val tick: IO[Unit] = Concurrent[IO].uncancelable(self.timer.sleep(10.seconds))
for {
_ <- IO(println("uncancellable"))
fiber <- Concurrent[IO].start(tick)
_ <- IO(println("seconds begin: " + FiniteDuration.apply(System.nanoTime(), TimeUnit.NANOSECONDS).toSeconds))
_ <- fiber.cancel
_ <- fiber.join
_ <- IO(println("seconds done : " + FiniteDuration.apply(System.nanoTime(), TimeUnit.NANOSECONDS).toSeconds))
} yield ()
}
private def notUncancellable: IO[Unit] = {
val tick: IO[Unit] = self.timer.sleep(10.seconds)
for {
_ <- IO(println("notUncancellable"))
fiber <- Concurrent[IO].start(tick)
_ <- IO(println("seconds begin: " + FiniteDuration.apply(System.nanoTime(), TimeUnit.NANOSECONDS).toSeconds))
_ <- fiber.cancel
_ <- fiber.join
_ <- IO(println("seconds done : " + FiniteDuration.apply(System.nanoTime(), TimeUnit.NANOSECONDS).toSeconds))
} yield ()
}
}
sbt:cats-effect-cancellation-question> run
[info] Compiling 1 Scala source to /Users/kevinmeredith/Workspace/cats-effect-cancellation-questions/target/scala-2.13/classes ...
[info] Done compiling.
[info] Packaging /Users/kevinmeredith/Workspace/cats-effect-cancellation-questions/target/scala-2.13/cats-effect-cancellation-question_2.13-0.1.jar ...
[info] Done packaging.
[info] Running net.App
uncancellable
seconds begin: 303045
seconds done : 303055
notUncancellable
seconds begin: 303055
^C$
notUncancellable
seconds begin: 303055
^C$
/**
* Returns a new task that will await for the completion of the
* underlying fiber, (asynchronously) blocking the current run-loop
* until that result is available.
*/
def join: F[A]