2016-05-16 6 views
2

私は、RESTfulサービスを照会するために非同期プレイWS Scala APIを使用しています。 WSClientによって呼び出されるリクエストURLを含むListをどのように処理することができますか(ただし、1回のリクエストで1秒あたり1リクエストしか許可されません)。論理的な観点からは、リストから要素(URL)を取得し、要求を行い、リストの次の要素に進む前に一定の時間待つことが考えられます。WS APIを再生する:リクエストレートを調整する

  • 良い古いThread.sleepを使用して、Playのような非ブロッキングと非同期のフレームワークでは、確かに悪い考えです。
  • ScheduledThreadPoolExecutorなどの新しいスレッドを生成する必要があるメソッドの場合は、同じことが考えられます。

Playの非同期スレッドと「スレッドなし」スレッドに悪影響を及ぼすことなくリクエストレートを調整するにはどうすればよいですか?

+0

プレイのバージョンは何? –

+0

再生バージョン2.5.3 – ceran

答えて

3

は、あなたが取得するために見てURLのリストを持っていると仮定します。我々flatMapFuture同じ値を1秒後に返す何かへのWebサービス呼び出しの結果。

Future.traverse(urls) { url => 
    wsClient.url(url).get().flatMap { result => 
    // potentially process `result` here 
    akka.pattern.after(1.second, actorSystem.scheduler)(Future.successful(result)) 
    } 
} // returns Future[List[WSResponse]] 

この

では、スコープ内で暗黙の ExecutionContextWSClientActorSystemコンポーネントが利用できるだけでなく、持っていることが必要です。

プレイの2.4.xでは

およびそれ以前、あなたがPromise.timeoutを使用して同じことを行うことができます:

Future.traverse(urls) { url => 
    wsClient.url(url).get().flatMap { result => 
    // potentially process `result` here 
    Promise.timeout(result, 1.second) 
    akka.pattern.after(1.second, actorSystem.scheduler)(Future.successful(result)) 
    } 
} 
1

アッカは、ここでは便利なスケジューラの機能があります。http://doc.akka.io/docs/akka/current/scala/scheduler.html

アッカは、プレイ中にすでにあるので、あなたが何かをインポートする必要はありません。
はそれはきれいなまたは簡単にテスト可能ではないでしょうが、あなたのようなものでした:また

val webserviceCall : Runnable = new Runnable { 

    override def run(): Unit = { 
     // do webservice call work 
     // figure out if you need to make more webservice calls, and if you do: 
     actorSystem.scheduler.scheduleOnce(0 seconds, 1 seconds, webserviceCall) 
    } 

} 

actorSystem.scheduler.scheduleOnce(0 seconds, webserviceCall) 

、誰かがしばらく前に作られたこのアッカメッセージスロットラーを使用することができます。http://doc.akka.io/docs/akka/snapshot/contrib/throttle.html

私はそれを使用しています以前(私はそれが昨年のAkka 2.3だったと思いますが)まだ動作するかどうかはわかりません。プレイ2.5.Xで

val urls = List(
    "http://www.google.com", 
    "http://stackoverflow.com", 
    "http://www.bing.com" 
) 

、我々はこれらの順に処理し、各呼び出しの間の非同期遅延を強制的にakka.pattern.afterを使用することができます。

関連する問題