Play でアプリを書きたかったのです。フレームワーク 2.2.x を非同期アプローチとplay.api.libs.iterattee
パッケージの演習として使用します。私がやりたかったのは、本文に大きなファイルのアップロードを含む POST 要求を取得し、それをチャンクごとに別の要求へのダウンロードとして送信することでした。
「Play for Scala」の本とこの例では、リクエスト内のファイルをチャンクで受け取り、Iteratee
custom で定義したものに蓄積または反復できますBodyParser
。チャンクされた応答の提供に関しては、応答に提供する必要がありますEnumerator
-同様Ok.chunked(enumerator)
に、列挙子が新しいチャンクを提供するときにクライアントに提供されます。
すべてをまとめたいと思ったので、アップロードするクライアントからダウンロードするクライアントに新しいデータ チャンクを非同期的に伝達するためのエレガントでリアクティブな方法を見つけることができないようです。Iteratee
によって受信されたデータ(この場合はBodyParser
) を新しいEnumerator
もの (この場合は応答に出力を提供するもの)に「転送」する良い方法はないようです。
私はそれを行うための2つの方法を思いつきましたが、どちらも私には十分ではないようです:
を使用してと
play.api.libs.iteratee.Concurrent.boradcast
を生成し、BodyParser 内で受信した各チャンクを にプッシュします。が持っているプロパティを持っていません - 列挙子は、適用されたものが古い値を消費するまで新しい値を生成しません。このようにすると、アップローダーがダウンローダーよりも高速なインターネット接続を持っていた場合、一度に 1 つのチャンクを処理するのではなく、ますます多くのメモリを使用する「膨張」が発生します。Channel
Enumerator
Channel
Channels
Enumerator
Iteratee
Channel
プロキシ akka
Actor
を作成し、アップロードされたファイルをチャンクごとに送信し、最後のファイルがダウンローダによって消費された後にのみ次のファイルを送信します。ただし、この場合、各チャンクがダウンローダに送信されることの確認はActor
、アップローダIteratee
が別のチャンクをプロキシに送信するように、プロキシを経由する必要があります。これは私にとって不要なオーバーヘッドのようです。
私の質問は2つあると思います:
Enumerator
によって受信された値を生成する「転送」を構築する簡単な方法はありIteratee
ますか?- 私のユースケースでは、Play と Scala の非同期ツールキットを使用して、考えているシナリオを実装する正しい方法は何ですか?