2017-12-20 15 views
0

HTTP GET要求をいくつか同時に送信し、すべての応答がタイムアウトするまで待機する関数を作成しているとします。少なくとも1つの応答がステータス200を持たないか、タイムアウトにならない場合、私の関数は失敗を返します。同時HTTP GET要求を送信する先

私はこのように、この機能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) 
} 

それは理にかなっていますか? タイムアウトの場合に将来のインスタンスがリークしませんか?

+0

あなたは内包を調べましたか?ここでそれを使用する方法についての良い記事です:http://danielwestheide.com/blog/2013/01/09/the-neophytes-guide-to-scala-part-8-welcome-to-the-future.html –

+0

for-comprehensionは、先物を同時に実行するのではなく順番に実行します。 – Michael

+0

事前に宣言していない場合。 あなたはval x = Future {}を実行できます。 {result < - x} の代わりに、{result < - Future {}} –

答えて

1

未来のタイムアウトのうちの1つがタイムアウトした場合、未来のものは引き続き実行され、実行コンテキストで引き続き実行されるため、残りの未来は実行され続けます。あなたができることは、Urlsを折り畳むことですが、これはそれらを連続して実行します。

urls.foldleft(Future.sucessful(Seq.empty)) { (future, url) => 
    future.flatMap(accum => futureGet(url).map(accum :+ _)) 
} 
関連する問題