2017-12-22 3 views
0
def resolve(url: String): Future[WSResponse] = ws.url(url).withFollowRedirects(true).get() 

def validateAllLinks(links: List[String]) = ??? 

Wie würden Sie die zweite Funktion lösen?Wie kann ich eine Liste von http-URLs gleichzeitig mit ScalaWS auflösen (Play!)?

ich Traverse versucht habe, Future.sequence, Await ...

Dies war mein letzter Versuch:

def validateAllLinks(links: List[String]) = links.map(link => 
    Await.result(resolve(link), Duration.create(3, TimeUnit.SECONDS)) 
) 

Das Problem bei diesem Ansatz:

  1. i erhalten TimeoutExceptions und MaxRedirectException, die ich nicht versuchen/fangen möchte

  2. Ich glaube nicht, dass die Lösung gleichzeitig wäre, auch wenn sie funktioniert.

Vielen Dank im Voraus!

Antwort

2

Fühlen Sie sich frei Future.sequence zu verwenden, werden sie parallel ausgeführt werden:

def validateAllLinks(links: List[String]): Future[List[WSResponse]] = 
    Future.sequence(links.map(resolve)) 

Wenn Sie Await.result nach Future.sequence nennen, ist es für die parallele Operationen abzuschließen warten:

import scala.concurrent.duration._ 
def validateAllLinks(links: List[String]): List[WSResponse] = 
    Await.result(Future.sequence(links.map(resolve)), 10 seconds) 

Aber bitte bedenken Sie, dass Await.result als eine schlechte Praxis gilt, sollten Sie versuchen, die Future zurückgeben, und lassen Sie den Clien t entscheiden, wie man damit umgeht.

Ein wenig mehr Details darüber, warum ist es eine schlechte Praxis:

  1. https://monix.io/docs/2x/best-practices/blocking.html

  2. https://github.com/alexandru/scala-best-practices/blob/master/sections/4-concurrency-parallelism.md#45-should-not-block

+0

Richtig, aber es gibt ein Problem bei diesem Ansatz, dass es nicht der Fall ist erlauben Zeitüberschreitungen und Fehler für einzelne Anfragen zu behandeln. Wahrscheinlich dieser Link: https://stackoverflow.com/questions/17466889/run-multiple-futures-in-parallel-return-default-value-on-timeout hilft. – igorpcholkin

+0

Richtig, meine Lösung war, es gleichzeitig zu machen. Um die Zeitüberschreitungen zu behandeln, sollte 'ws.url (url) .withRequestTimeout (timeout) 'in der resolve-Methode verwendet werden. Und "resolve (..). Map (..). Recovery (..)" sollte verwendet werden, um zu verstehen, welche fehlschlagen und welche erfolgreich sind. – Feyyaz

Verwandte Themen