【问题标题】:Futures to send concurrent HTTP GET requests发送并发 HTTP GET 请求的期货
【发布时间】:2017-12-21 06:01:25
【问题描述】:

假设我正在编写一个函数来发送几个并发的 HTTP GET 请求并等待所有响应超时。如果至少一个响应没有状态 200 或不在超时内,我的函数应该返回失败。

我正在像这样写这个函数tryGets

import java.net.URL

import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext, Future}
import scala.util.Try

def unsafeGet(url: URL): String = {
  val in = url.openStream()
  scala.io.Source.fromInputStream(in).mkString
}

def futureGet(url: URL)
             (implicit ec: ExecutionContext): Future[String] = Future {
  unsafeGet(url)
}

def tryGets(urls: Seq[URL], timeOut: Duration)
            (implicit ec: ExecutionContext): Try[Seq[String]] = Try {
  val fut = Future.sequence(urls.map(futureGet))
  Await.result(fut, timeOut)
}

这有意义吗? 如果超时,它不会泄漏未来的实例吗?

【问题讨论】:

  • 您是否考虑过理解?这是一篇关于如何使用它的好文章:danielwestheide.com/blog/2013/01/09/…
  • for-comprehension 按顺序而不是同时执行期货。
  • 如果您提前声明它们,则不会。所以你可以做 val x = Future{}; for{result
  • 这里有一个很好的解释:alvinalexander.com/scala/…
  • 谢谢。我知道了。一旦我在理解之前实例化期货,它们就会同时运行。

标签: scala concurrency future resource-leak


【解决方案1】:

如果 Future 中的一个超时,那么 Future 的其余部分将继续执行,因为 Future 是急切的,并将继续在执行上下文上运行。您可以做的是折叠 Urls,但这将串行执行它们。

urls.foldleft(Future.sucessful(Seq.empty)) { (future, url) =>
  future.flatMap(accum => futureGet(url).map(accum :+ _))
}

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 2019-08-15
    • 2016-08-04
    • 1970-01-01
    相关资源
    最近更新 更多