2017-05-05 4 views
1

Play 2.5アプリケーションでは、1つのトランザクション内のデータベースから大量のデータを読み取り、それをHTTPレスポンスとしてクライアントに送信するサービスを作成する必要があります。チャンクされたレスポンスへのOutputStream

ネットワークの速度が遅いと、データベースからデータを取得するために使用されたDB接続が長時間使用される可能性があるため、背圧をかけたくありません。

現在の実装では、最初のデータを一時バッファ(データが多すぎる場合はメモリまたはファイル)に抽出し、DB接続を解放し、データでOk応答を返します。

欠点は、データがデータベースから完全に抽出されると、クライアントへのデータの送信が最初に開始されることです。

データをある種のソースに抽出する方が良いと思います。たとえば、10kB以上の場合はすべてのデータをメモリとディスクにバッファリングしますが、チャンクされた応答にすぐにデータを提供します。

私はこれを実装する予定が、私は右のそれを取得し、マルチスレッドに関するいくつかの微妙なバグを実装する、などの任意のヒントを事前に

おかげで、ガイドライン、既存のオープンな実装をブロックしていないだろうかと思います。 ..

答えて

1

ファイルを中間バッファとして使用している場合は、「すべてのデータをバッファするソース」として機能します。ファイルは同時に書き込んだり読み込んだりすることができます(これは* nixシステムでは当てはまりますが、ウィンドウについてはわかりません)。したがって、データベースデータを使用してファイルに書き込み、ファイルデータを使用してクライアントに応答することができます。

リクエストが来たら、データベースクエリを開始し、出力をappend modeにバッファファイルに転送します。

この書き込みが行われている間、エンティティがファイルによって読み込みモードで供給されている状態で、クライアントにhttp応答を同時に送信します。

「マルチスレッド、ブロックなどに関する微妙なバグ」を心配する必要はありません。あなたがOSとファイルシステムにあなたの仕事の大半をさせているからです。

+0

Thansk。私はそのアプローチを試みます。それでもまだ理想的ではありません。少量のデータしかない場合は、すべてをメモリに入れておきたいと思います。もう1つの質問は、プロデューサがすべてのデータを書き込む前に、プロデューサがコンシューマよりも遅く、ファイルの現在の最後に達した場合はどうなりますか? –

+0

@GregorRaýmanあなたはようこそ。 「少量のデータしかない」ということは、「たくさんのデータを読み取るサービスを作成する必要がある」という元の質問と矛盾します。プロダクションがコンシューマーよりも遅い場合は、ファイルリーダーがEOFに達するまで続行するので、これは問題ありません(これは、すべてのファイルリーダーが最低レベルのioストリームを持つ理由です)。 –

+0

ラモーンありがとう、私はアプローチを試してみます。私が持っている問題は、少量のデータ(数kB)または大量のデータ(数十MB)があるかどうかはわからないということです。そのため、現在のところ、データがメモリにバッファされ、設定されたしきい値をオーバーフローするとファイルに切り替わります。これは、待ち時間のために理想的ではないし、消費者が十分な速さであれば、たとえデータがたくさんあるとしても、ファイルを完全に避けることができるからです。 –

関連する問題