Я создаю службу отчетов, где один процесс отправляет запрос, извлекает токен, а затем передает токен другому процессу, из которого мы запрашиваем службу отчетов и возвращаем результаты обратно.
Учитывая этот код, как мне реализовать блокирующий вызов, пока paused не станет ложным?
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
}
Вот диаграмма взаимодействия, объясняющая, чего я пытаюсь достичь:
http://teksol.info.s3.amazonaws.com/reporting-service.png
- Веб-браузер запрашивает отчет у внешнего веб-сервера
- Интерфейс веб-сервера запрашивает у службы отчетов токен, относящийся к конкретному запросу
- Одновременно служба отчетов подключается к PostgreSQL и отправляет запрос
- Веб-сервер внешнего интерфейса возвращает URL-адрес и токен службы отчетов в веб-браузер.
- Веб-браузер отправляет Ajax-запрос (длинный опрос) службе отчетов с возвращенным токеном
- Служба отчетов направляет строки, когда они возвращаются в веб-браузер
Поскольку все асинхронно, шаг 3 может начать возвращать данные до подключения веб-браузера, что может привести к потере данных. Я мог бы буферизовать данные в памяти до тех пор, пока клиент не вернется, но я бы предпочел заблокировать передачу строк данных, так как это предотвратило бы использование ОЗУ. Или, может быть, я просто шучу, а оперативная память все еще будет использоваться в основной библиотеке? Во всяком случае, указатели оценили!