【问题标题】:Do Scala futures support for non-blocking combinators such as firstNCompletedOf and firstNSuccCompletedOf?Scala 期货是否支持非阻塞组合子,例如 firstNCompletedOf 和 firstNSuccCompletedOf?
【发布时间】:2019-02-23 19:04:05
【问题描述】:

例如,Folly 支持非阻塞组合器 collectN,可以在这里找到 https://github.com/facebook/folly/blob/master/folly/futures/helpers.h

它不提供非阻塞组合器 collectNWithoutException,它只会收集类似于 collectAny 的成功期货,但会收集多个结果未来。

Scala 似乎只提供了 firstCompletedOf,它是 collectN 且 n == 1。

如果 Scala 不支持这些非阻塞组合器,我如何轻松实现它们? 我想使用现有的组合器来实现。

【问题讨论】:

    标签: scala future


    【解决方案1】:

    这里是collectN

    def collectN[T](n: Int, futures: List[Future[T]]): Future[List[T]] =  {
      val promise = Promise[List[T]]
      var result:List[T] = Nil
      futures.foreach {
         _.onComplete { 
           case _ if result.length >= n => 
           case Success(t) => synchronized {            
             result = t :: result
             if(result.length == n) promise.success(result.reversed.take(n))          
           }
           case Failure(x) => promise.failure(x) 
         }
      }
      promise.future
    }
    

    注意,如果输入期货的数量小于 n(并且它们都成功),它会返回一个永远不会完成的 Future。 您可以对其进行简单的修改,以继续等待 N 次成功,而不是在第一次失败后中止,但如果少于 N 次的期货最终成功,那也将永远等待。为避免这种情况,您可以计算已完成的数量,并在达到原始列表的大小后退出。

    【讨论】:

    • 嗯,这是我自己实现的方式,但之前检查了 futures.size >= n。它与 Folly 的实现类似,因此答案是:Scala 不支持它们,但您可以在 Promise 的帮助下实现与 Folly 类似的方式。
    【解决方案2】:

    这对于大量期货不实用,但对可用组合器的演示

      def firstNCompleted[T](n: Int, futures: List[Future[T]])(implicit executor: ExecutionContext): Future[List[T]] =
        Future.firstCompletedOf(futures.combinations(n).map(Future.sequence(_)))
    
    • 创建 n 个期货的所有组合Iterator[List[Future[T]]]
    • 将每个组合排序到结果列表的未来Iterator[Future[List[T]]]
    • 返回第一个完成的Future[List[T]]

    【讨论】:

    • 或许你应该把"This is not practice for large number of futures"移到代码sn-p之前,不然有点太震撼了。还应注意,一旦其中一个期货完成,其他期货不会以任何方式取消。
    • 很好,但是 firstNSuccCompleted 呢?
    • Scala 没有仅用于成功期货的组合器,您需要编写自己的函数,如@Dima 答案。否则,我建议使用 Monix 或 RxScala reactivex.io/documentation/operators/take.html 看看 reactx 模式
    猜你喜欢
    • 2016-09-29
    • 2013-04-03
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    相关资源
    最近更新 更多