From a797086d89d40b2fa838aaa28c9fb443099c8bf1 Mon Sep 17 00:00:00 2001 From: yuta25 Date: Wed, 6 Jan 2016 19:09:41 +0900 Subject: [PATCH] Add dispose support --- lib/command.js | 55 ++++++++++++++++++++++++++++++++++++++++--------- test/dispose.js | 45 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 test/dispose.js diff --git a/lib/command.js b/lib/command.js index 9811f739..9fd13a77 100644 --- a/lib/command.js +++ b/lib/command.js @@ -211,6 +211,7 @@ module.exports = function (proto) { , self = this , proc, err , timeout = parseInt(this._options.timeout) + , disposers = this._options.disposers , timeoutId; debug(cmd); @@ -228,15 +229,18 @@ module.exports = function (proto) { if (timeout) { timeoutId = setTimeout(function(){ - err = new Error('gm() resulted in a timeout.'); - cb(err); - if (proc.connected) { - proc.stdin.pause(); - proc.kill(); - } + dispose('gm() resulted in a timeout.'); }, timeout); } + if (disposers) { + disposers.forEach(function(disposer) { + disposer.events.forEach(function(event) { + disposer.emitter.on(event, dispose); + }); + }); + } + if (self.sourceBuffer) { proc.stdin.write(this.sourceBuffer); proc.stdin.end(); @@ -311,12 +315,22 @@ module.exports = function (proto) { if (cb.called) return; if (timeoutId) clearTimeout(timeoutId); cb.called = 1; - if (args[0] !== 'identify' && bin !== 'identify') { - self._in = []; - self._out = []; - } + if (args[0] !== 'identify' && bin !== 'identify') { + self._in = []; + self._out = []; + } callback.call(self, err, stdout, stderr, cmd); } + + function dispose (msg) { + var message = msg ? msg : 'gm() was disposed'; + err = new Error(message); + cb(err); + if (proc.exitCode === null) { + proc.stdin.pause(); + proc.kill(); + } + } } /** @@ -408,4 +422,25 @@ module.exports = function (proto) { return rgx.test(this.source); } + + /** + * add disposer (like 'close' of http.IncomingMessage) in order to dispose gm() with any event + * + * @param {EventEmitter} emitter + * @param {Array} events + * @return {Object} gm + * @example + * command.addDisposer(req, ['close', 'end', 'finish']); + */ + + proto.addDisposer = function addDisposer (emitter, events) { + if (!this._options.disposers) { + this._options.disposers = []; + } + this._options.disposers.push({ + emitter: emitter, + events: events + }); + return this; + }; } diff --git a/test/dispose.js b/test/dispose.js new file mode 100644 index 00000000..585cc742 --- /dev/null +++ b/test/dispose.js @@ -0,0 +1,45 @@ +var assert = require('assert'); + +module.exports = function (img, dir, finish, gm) { + var EventEmitter = require('events').EventEmitter; + EventEmitter.prototype._maxListeners = 100; + + assert.equal(undefined, gm.prototype._options.disposers); + assert.equal(undefined, img._options.disposers); + + emitter = new EventEmitter(); + + disposer = { + emitter: emitter, + events: ['pleaseDispose', 'readyToDispose'] + }; + + var g = gm('test').options({ disposers: [ disposer ] }); + assert.deepEqual([disposer], g._options.disposers); + + var sub = gm.subClass({ disposers: [ disposer ]}); + assert.deepEqual([disposer], sub.prototype._options.disposers); + + if (!gm.integration) { + return finish(); + } + + gm(dir + '/photo.JPG').options({ disposers: [ disposer ]}) + .thumb(1000, 1000, dir + '/dispose.png', function (err) { + assert.ok(err, "Expecting a disposed error"); + }); + + emitter.emit('pleaseDispose'); + + noDispose(); + + function noDispose() { + gm(dir + '/photo.JPG').options({ disposers: [ disposer ]}) + .thumb(1000, 1000, dir + '/dispose.png', function (err) { + delete emitter; + delete disposer; + finish(err); + }); + emitter.emit('disposeOK'); + } +}