あるプロセスがクエリを送信し、トークンを取得し、トークンを別のプロセスに渡し、そこからレポート サービスにクエリを実行し、結果をストリーミングするレポート サービスを構築しています。
このコードを考えると、一時停止が false になるまでブロッキング呼び出しを実装するにはどうすればよいですか?
var util = require('util')
, events = require('events')
, pg = require('pg')
// QueryHandler is an EventEmitter
function QueryHandler(sql) {
this.paused = true
pg.connect(connectionString, function(err, client) {
// error handling ignored for sake of illustration
var query = client.query(sql)
query.on('row', function(row) {
if (this.paused) {
// Somehow block until paused === false
}
this.emit(row)
}.bind(this))
}.bind(this))
}
util.inherits(QueryHandler, events.EventEmitter)
QueryHandler.prototype.resume = function() {
this.paused = false
}
これは、私が達成しようとしていることを説明する相互作用図です。
- Web ブラウザーがフロントエンド Web サーバーにレポートを要求します。
- フロントエンド Web サーバーは、特定のクエリに関連するトークンをレポート サービスに要求します。
- 同時に、レポート サービスが PostgreSQL に接続し、クエリを送信します。
- フロントエンド Web サーバーは、レポート サービスの URL とトークンを Web ブラウザーに返します。
- Web ブラウザーは、返されたトークンを使用してレポート サービスに対して Ajax (ロング ポーリング) 要求を実行します。
- レポーティング サービスは、行が Web ブラウザーに戻ってきたときに行をストリーミングします。
すべてが非同期であるため、Web ブラウザーが接続する前にステップ 3 でデータが返される可能性があり、これはデータの損失を意味します。クライアントが戻ってくるまでデータをメモリにバッファリングすることもできますが、RAM の使用が妨げられるため、データ行の発行をブロックしたいと思います。それとも、冗談で、基礎となるライブラリでRAMが引き続き使用されるのでしょうか? とにかく、ポインターは大歓迎です!