如果花费太长时间取消对并行集合的操作 - Scala

时间:2017-12-12 23:54:19

标签: scala concurrency scala-collections

是否可以取消对并行scala集合的操作?例如,如果我myList.par.map(...),是否可以在以后取消,并获取已经处理过的元素?

2 个答案:

答案 0 :(得分:3)

取消对List的操作可能无法实现,因为Scala库中没有API来执行此操作。但你有一些选择来完成这项工作。例如,如果您的List是一个流,并且该流包含在Future中,如下所示:

scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global

scala> val stream = scala.concurrent.Future { 1 #:: 2 #:: 3 #:: Stream.empty }
stream: scala.concurrent.Future[scala.collection.immutable.Stream[Int]] = Success(Stream(1, ?))

你可以随时取消未来 - 基于一些超时!

另一种选择是使用Observables和Observer(被动的),你可以将List建模为Observable,并使用Observer订阅Observable。然后,您可以在任何您想要的时间点取消订阅者!如果您对此感兴趣,请查看Monix库!

答案 1 :(得分:0)

我找不到内置的答案 - 我决定只设置一个时间限制,如果经过的时间越过阈值,迭代就会停止运行。

val MAX_TIME: Long = 120.minutes.toMillis
val start = System.currentTimeMillis()
val isTimeRemaining = () => (System.currentTimeMillis() - start) <= MAX_TIME

val processor:Seq[R] = (i:T) => {
  if (isTimeRemaining())
     //do some processing here
  else
    Nil
}

val results:Seq[T] = Random.shuffle(instances)
                      .par
                     .flatMap(processor)
                     .filterNot(_.isEmpty)
                     .toList