From 2a93f06e276f3adb76e494ae9198da38799d493c Mon Sep 17 00:00:00 2001 From: Guillermo Rauch Date: Sat, 14 Jan 2012 09:35:39 -0800 Subject: [PATCH] Implemented draining and orderly close to polling. --- lib/transports/polling.js | 59 +++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/lib/transports/polling.js b/lib/transports/polling.js index 3d6c38dcc..a235baeaf 100644 --- a/lib/transports/polling.js +++ b/lib/transports/polling.js @@ -90,8 +90,14 @@ Polling.prototype.onPollRequest = function (req, res) { req.cleanup = cleanup; req.on('close', onClose); - this.buffer = false; - this.flush(); + this.writable = true; + this.emit('drain'); + + // if we're still writable but had a pending close, trigger an empty send + if (this.writable && this.shouldClose) { + debug('triggering empty send to append close packet'); + this.send([]); + } } }; @@ -162,41 +168,22 @@ Polling.prototype.onData = function (data) { }; /** - * Flushes buffers. - * - * @api private - */ - -Polling.prototype.flush = function () { - if (this.writeBuffer) { - this.write(parser.encodePayload(this.writeBuffer)); - this.writeBuffer = null; - this.emit('drain'); - } -}; - -/** - * Writes a packet. + * Writes a packet payload. * * @param {Object} packet - * @param {Function} called when the packet is dispatched * @api private */ -Polling.prototype.send = function (packet, fn) { - if (this.buffer) { - if (!this.writeBuffer) { - this.writeBuffer = []; - } - - debug('poll buffering packet: type %s | data %s', packet.type, packet.data); - this.writeBuffer.push(packet); - if (fn) this.once('drain', fn); - } else { - debug('poll writing packet: type %s | data %s', packet.type, packet.data); - this.write(parser.encodePayload([packet])); - if (fn) fn(); +Polling.prototype.send = function (packets) { + debug('polling writing packets', JSON.stringify(packets)); + if (this.shouldClose) { + debug('appending close packet to payload'); + packets.push({ type: 'close' }); + this.shouldClose(); + this.shouldClose = null; } + + this.write(parser.encodePayload(packets)); }; /** @@ -209,7 +196,7 @@ Polling.prototype.send = function (packet, fn) { Polling.prototype.write = function (data) { this.doWrite(data); this.req.cleanup(); - this.buffer = true; + this.writable = false; }; /** @@ -225,5 +212,11 @@ Polling.prototype.doClose = function (fn) { this.dataReq.abort(); } - this.send({ type: 'close' }, fn); + if (this.writable) { + debug('polling transport is writable - closing right away'); + this.send([{ type: 'close' }]); + } else { + debug('polling transport not writable - marking that we should close'); + this.shouldClose = fn; + } };