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

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

どのように2番目の機能を解決しますか?ScalaWS(Play!)と並行してhttp-URLのリストを解決するには?

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

このアプローチの問題:私は取得

  1. 私はトラバース、Future.sequence、待つを試してみました

    ...

    は、これは私の最も最近の試みでしたTimeoutExceptionsとMaxRedirectExceptionを試してみたい/キャッチしたくないと思う。

  2. 私は解決策が並行しているとは思わない、たとえそれが働いても。

ありがとうございます!

答えて

2

は、彼らが並行して実行され、Future.sequence自由に利用して構い:

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

あなたはFuture.sequenceAwait.resultを呼び出すと、それが完了するまでに並列処理を待ちます:

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

しかし、Await.resultは悪い習慣とみなされますので、Futureを返すようにしてください。どのようにそれを処理するかを決める。

それは悪い習慣だ理由について、もう少し詳しく:

  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

正しい、しかし、それはないことを、このアプローチに問題があります個々の要求のタイムアウトとエラーを処理できます。おそらくこのリンク:https://stackoverflow.com/questions/17466889/run-multiple-futures-in-parallel-return-default-value-on-timeoutが役立ちます。 – igorpcholkin

+0

そうですね、私の解決策はそれを並行させることでした。タイムアウトを処理するには、resolveメソッドで 'ws.url(url).withRequestTimeout(timeout)'を使うべきです。そして、 'resolve(..)。map(..)。recovery(..)'はどのマップが失敗し、どのマップが成功するかを理解するために使われるべきです。 – Feyyaz

関連する問題