2017-12-20 1 views
0

Angenommen, ich schreibe eine Funktion, um einige gleichzeitige HTTP-GET-Anforderungen zu senden und auf alle Antworten mit einem Timeout zu warten. Wenn mindestens eine Antwort nicht den Status 200 hat oder nicht innerhalb des Zeitlimits liegt, sollte die Funktion einen Fehler zurückgeben.Futures zum Senden gleichzeitiger HTTP-GET-Anforderungen

Ich schreibe diese Funktion tryGets wie folgt aus:

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) 
} 

Ist es sinnvoll? Gibt es keine zukünftigen Instanzen im Falle einer Zeitüberschreitung?

+0

Haben Sie nach einem Verständnis gesucht? Hier ist ein guter Artikel darüber, wie man es benutzt: http://danielwestheide.com/blog/2013/01/09/the-neophytes-guide-to-scala-part-8-welcome-to-the-future.html –

+0

für das Verständnis führt Futures sequentiell anstatt gleichzeitig. – Michael

+0

Nicht, wenn Sie sie im Voraus deklarieren. Sie können also val x = Future {}; für {result <- x} Anstelle von {result <- Future {}} –

Antwort

1

Wenn eine der Futures ausläuft, dann wird der Rest der Future weiterhin ausgeführt, weil die Zukunft eifrig ist und weiterhin im Ausführungskontext laufen wird. Was Sie tun könnten, ist über die URLs zu falten, aber dies wird sie seriell ausführen.

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