diff --git a/API.md b/API.md index de42c188..3f6dd246 100644 --- a/API.md +++ b/API.md @@ -153,14 +153,14 @@ the current connection. var redis = new Redis(); redis.monitor(function (err, monitor) { // Entering monitoring mode. - monitor.on('monitor', function (time, args) { + monitor.on('monitor', function (time, args, source, database) { console.log(time + ": " + util.inspect(args)); }); }); // supports promise as well as other commands redis.monitor().then(function (monitor) { - monitor.on('monitor', function (time, args) { + monitor.on('monitor', function (time, args, source, database) { console.log(time + ": " + util.inspect(args)); }); }); @@ -218,6 +218,7 @@ Create a Redis instance * [new Cluster(startupNodes, options)](#new_Cluster_new) * [.connect()](#Cluster+connect) ⇒ Promise * [.disconnect()](#Cluster+disconnect) + * [.quit(callback)](#Cluster+quit) ⇒ Promise * [.nodes([role])](#Cluster+nodes) ⇒ [Array.<Redis>](#Redis) * [.getBuiltinCommands()](#Commander+getBuiltinCommands) ⇒ Array.<string> * [.createBuiltinCommand(commandName)](#Commander+createBuiltinCommand) ⇒ object @@ -258,6 +259,19 @@ Disconnect from every node in the cluster. **Kind**: instance method of [Cluster](#Cluster) **Access:** public + + +### cluster.quit(callback) ⇒ Promise +Quit the cluster gracefully. + +**Kind**: instance method of [Cluster](#Cluster) +**Returns**: Promise - return 'OK' if successfully +**Access:** public + +| Param | Type | +| --- | --- | +| callback | function | + ### cluster.nodes([role]) ⇒ [Array.<Redis>](#Redis) diff --git a/lib/cluster/index.js b/lib/cluster/index.js index e1bd887f..d4afb21e 100644 --- a/lib/cluster/index.js +++ b/lib/cluster/index.js @@ -208,6 +208,29 @@ Cluster.prototype.disconnect = function (reconnect) { this.connectionPool.reset([]); }; +/** + * Quit the cluster gracefully. + * + * @param {function} callback + * @return {Promise} return 'OK' if successfully + * @public + */ +Cluster.prototype.quit = function (callback) { + this.setStatus('disconnecting'); + + this.manuallyClosing = true; + + if (this.reconnectTimeout) { + clearTimeout(this.reconnectTimeout); + this.reconnectTimeout = null; + } + return Promise.all(this.nodes().map(function (node) { + return node.quit(); + })).then(function () { + return 'OK'; + }).nodeify(callback); +}; + /** * Get nodes with the specified role * diff --git a/test/functional/cluster.js b/test/functional/cluster.js index 1cb353ac..cf8e044c 100644 --- a/test/functional/cluster.js +++ b/test/functional/cluster.js @@ -1284,6 +1284,40 @@ describe('cluster', function () { }); }); }); + + describe('#quit()', function () { + it('should quit the connection gracefully', function (done) { + var slotTable = [ + [0, 1, ['127.0.0.1', 30001]], + [2, 16383, ['127.0.0.1', 30002], ['127.0.0.1', 30003]] + ]; + var argvHandler = function (argv) { + if (argv[0] === 'cluster' && argv[1] === 'slots') { + return slotTable; + } + }; + var node1 = new MockServer(30001, argvHandler); + var node2 = new MockServer(30002, argvHandler); + var node3 = new MockServer(30003, argvHandler); + + var cluster = new Redis.Cluster([ + { host: '127.0.0.1', port: '30001' } + ]); + + var setCommandHandled = false; + cluster.on('ready', function () { + cluster.set('foo', 'bar', function () { + setCommandHandled = true; + }); + cluster.quit(function (err, state) { + expect(setCommandHandled).to.eql(true); + expect(state).to.eql('OK'); + cluster.disconnect(); + disconnect([node1, node2, node3], done); + }); + }); + }); + }); }); function disconnect(clients, callback) {