From 60e9d0fdd60d53021581402537b8379f2c346ea0 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Wed, 14 Oct 2015 00:58:27 +0200 Subject: [PATCH] Fix multi regression. Closes #889 Allow commands being executed after a Multi / Batch was initiated but not yet executed --- index.js | 15 +++++++------- test/batch.spec.js | 6 ++++++ test/commands/multi.spec.js | 41 +++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index c846fa5b60..8988aa68d9 100644 --- a/index.js +++ b/index.js @@ -869,14 +869,9 @@ RedisClient.prototype.end = function (flush) { return this.stream.destroySoon(); }; -function Multi(client, args, transaction) { - client.stream.cork(); +function Multi(client, args) { this._client = client; this.queue = new Queue(); - if (transaction) { - this.exec = this.exec_transaction; - this.EXEC = this.exec_transaction; - } var command, tmp_args; if (Array.isArray(args)) { while (tmp_args = args.shift()) { @@ -892,11 +887,13 @@ function Multi(client, args, transaction) { } RedisClient.prototype.multi = RedisClient.prototype.MULTI = function (args) { - return new Multi(this, args, true); + var multi = new Multi(this, args); + multi.exec = multi.EXEC = multi.exec_transaction; + return multi; }; RedisClient.prototype.batch = RedisClient.prototype.BATCH = function (args) { - return new Multi(this, args, false); + return new Multi(this, args); }; commands.forEach(function (fullCommand) { @@ -1077,6 +1074,7 @@ Multi.prototype.exec_transaction = function (callback) { var cb; this.errors = []; this.callback = callback; + this._client.stream.cork(); this._client.pipeline = len + 2; this.wants_buffers = new Array(len); this.send_command('multi', []); @@ -1194,6 +1192,7 @@ Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = funct return true; } this.results = new Array(len); + this._client.stream.cork(); this._client.pipeline = len; var lastCallback = function (cb) { return function (err, res) { diff --git a/test/batch.spec.js b/test/batch.spec.js index 3fb5e392a4..27b45ad3f0 100644 --- a/test/batch.spec.js +++ b/test/batch.spec.js @@ -72,6 +72,12 @@ describe("The 'batch' method", function () { }); }); + it("runs normal calls inbetween batch", function (done) { + var batch = client.batch(); + batch.set("m1", "123"); + client.set('m2', '456', done); + }); + it("returns an empty array if promisified", function () { return client.batch().execAsync().then(function(res) { assert.strictEqual(res.length, 0); diff --git a/test/commands/multi.spec.js b/test/commands/multi.spec.js index 44ac2c9c58..7ebfc63b29 100644 --- a/test/commands/multi.spec.js +++ b/test/commands/multi.spec.js @@ -73,6 +73,47 @@ describe("The 'multi' method", function () { assert.strictEqual(notBuffering, true); }); + it("runs normal calls inbetween multis", function (done) { + var multi1 = client.multi(); + multi1.set("m1", "123"); + client.set('m2', '456', done); + }); + + it("runs simultaneous multis with the same client", function (done) { + var end = helper.callFuncAfter(done, 2); + + var multi1 = client.multi(); + multi1.set("m1", "123"); + multi1.get('m1'); + + var multi2 = client.multi(); + multi2.set("m2", "456"); + multi2.get('m2'); + + multi1.exec(end); + multi2.exec(function(err, res) { + assert.strictEqual(res[1], '456'); + end(); + }); + }); + + it("runs simultaneous multis with the same client version 2", function (done) { + var end = helper.callFuncAfter(done, 2); + var multi2 = client.multi(); + var multi1 = client.multi(); + + multi2.set("m2", "456"); + multi1.set("m1", "123"); + multi1.get('m1'); + multi2.get('m2'); + + multi1.exec(end); + multi2.exec(function(err, res) { + assert.strictEqual(res[1], '456'); + end(); + }); + }); + it('roles back a transaction when one command in a sequence of commands fails', function (done) { var multi1, multi2; var expected = helper.serverVersionAtLeast(client, [2, 6, 5]) ? helper.isError() : function () {};