如果另一个任务失败,如何组合两个并行任务来取消一个任务?

Mic*_*ael 8 concurrency scala task scalaz

我想用 scalaz.concurrent.Task实现我的异步处理.我需要一个函数(Task[A], Task[B]) => Task[(A, B)]来返回一个工作如下的新任务:

  • 并行运行Task[A]Task[B]等待结果;
  • 如果其中一个任务失败,则取消第二个任务并等待它终止;
  • 返回两个任务的结果.

你会如何实现这样的功能?

Tra*_*own 3

正如我上面提到的,如果您不关心实际停止非失败的计算,您可以使用Nondeterminism. 例如:

import scalaz._, scalaz.Scalaz._, scalaz.concurrent._

def pairFailSlow[A, B](a: Task[A], b: Task[B]): Task[(A, B)] = a.tuple(b)

def pairFailFast[A, B](a: Task[A], b: Task[B]): Task[(A, B)] =
  Nondeterminism[Task].both(a, b)

val divByZero: Task[Int] = Task(1 / 0)
val waitALongTime: Task[String] = Task {
  Thread.sleep(10000)
  println("foo")
  "foo"
}
Run Code Online (Sandbox Code Playgroud)

进而:

pairFailSlow(divByZero, waitALongTime).run // fails immediately
pairFailSlow(waitALongTime, divByZero).run // hangs while sleeping
pairFailFast(divByZero, waitALongTime).run // fails immediately
pairFailFast(waitALongTime, divByZero).run // fails immediately
Run Code Online (Sandbox Code Playgroud)

waitALongTime除了第一种情况外,在每种情况下都会发生副作用。如果您想尝试停止该计算,则需要使用类似Tasks的内容runAsyncInterruptibly