2016-06-23 13 views
0

私は常に新しい値をチェックする必要があるHTTP APIエンドポイントを持っています。幸いにも、それは長いポーリングをサポートしています。つまり、私はリクエストを行い、応答を待つ(最大10分)、レスポンスからいくらかの価値を得て、どこかに格納して別のリクエストをして副作用を生むという「無限ループ」を実装する必要があるということです。将来のFinagleでのリクエストの無限シーケンス

私はいくつかの関数を持っているので、呼び出しは '無限ループ'を開始します。また、Finagle APIを満たすためにClosableを返す必要があります。 HTTPリクエストが失敗した場合、すぐに再試行する必要があります。

これをFinagleのFutureで実装する方法を理解する必要があります。私は、将来の応答に変換を適用して再帰を使用できるかどうか疑問に思いますか?または何かが欠けていて、Finagleでそれを行うより簡単な方法がありますか?

ありがとうございます!

+0

私も同様の問題がありましたが、http4s/scalaz-stream 'time.awakeEvery.map()'で解決しました。 – Reactormonk

答えて

2

私はそれは(あなたが記述するもの)の再帰よりも、それ以上に簡単行うことができるか想像できるかわからない:これはと、実際に伝統的な意味での再帰的ではないことを、

def keepCalling: Future[Unit] = makeRequest 
    .flatMap { response => 
     processResponse(response) 
     if(cancelled) Future.Unit else keepCalling 
    } 

注意「再帰的な」呼び出しは別のスレッド上で行われるため、いつも(ある予約で)keepCallingの1つのインスタンスだけがスタックに置かれると期待する必要があります。

+0

ありがとう!つまり、サイクルごとにメモリ消費量が増加するということですか?またはScalaがそれを処理しますか? また、あなたは 'cancelled'をどのように扱いますか? 'var'ですか?それとももっと良い方法がありますか? – Ashald

+0

他のアプリケーションよりもメモリ消費を心配する必要があることを示すこのケースについては何も表示されません。私は、あなたがそれについて心配する必要があります、そして、あなたが正当な参照を公開していないならば、それは成長するでしょう、なぜ私はこの事件が他のものよりあなたをもう心配する必要があるのか​​分かりません。 'cancelled'を扱うのは...ええ、' var'だと思います。このようなシンプルなケースでは、何かを好きにする必要はありません。あるスレッドで行われた更新が他のスレッドによって正しく見られるように、必ず「volatile」にしてください。 – Dima

+0

スーパー感謝!最後に、 'makeRequest'が失敗の未来を返すかどうか? 「ループ」はブレーキを掛けるでしょうか? '再試行'をするために 'flatMap'ではなく何か他のものを使うべきでしょうか? – Ashald