我正在构建一个报告服务,其中一个进程提交查询,检索令牌,然后将令牌交给另一个进程,我们从中查询报告服务并将结果流回。
鉴于此代码,我应该如何实现阻塞调用,直到暂停为假?
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 服务器请求报告
- 前端网络服务器向报告服务请求与特定查询相关的令牌
- 同时,报告服务连接到 PostgreSQL 并发送查询
- 前端网络服务器将报告服务的 URL 和令牌返回给网络浏览器
- Web 浏览器使用返回的令牌向报告服务发出 Ajax(长轮询)请求
- 报告服务在行返回 Web 浏览器时对其进行流式传输
因为一切都是异步的,所以第 3 步可能会在 Web 浏览器连接之前开始返回数据,这意味着数据丢失。我可以在内存中缓冲数据,直到客户端回来,但我宁愿阻止数据行的发射,因为这会阻止 RAM 的使用。或者也许我只是在开玩笑,RAM 仍然会在底层库中使用?无论如何,指针表示赞赏!