1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00

Fix multi regression. Closes #889

Allow commands being executed after a Multi / Batch was initiated but not yet executed
This commit is contained in:
Ruben Bridgewater
2015-10-14 00:58:27 +02:00
parent 28d343c2ad
commit 60e9d0fdd6
3 changed files with 54 additions and 8 deletions

View File

@@ -869,14 +869,9 @@ RedisClient.prototype.end = function (flush) {
return this.stream.destroySoon(); return this.stream.destroySoon();
}; };
function Multi(client, args, transaction) { function Multi(client, args) {
client.stream.cork();
this._client = client; this._client = client;
this.queue = new Queue(); this.queue = new Queue();
if (transaction) {
this.exec = this.exec_transaction;
this.EXEC = this.exec_transaction;
}
var command, tmp_args; var command, tmp_args;
if (Array.isArray(args)) { if (Array.isArray(args)) {
while (tmp_args = args.shift()) { while (tmp_args = args.shift()) {
@@ -892,11 +887,13 @@ function Multi(client, args, transaction) {
} }
RedisClient.prototype.multi = RedisClient.prototype.MULTI = function (args) { 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) { RedisClient.prototype.batch = RedisClient.prototype.BATCH = function (args) {
return new Multi(this, args, false); return new Multi(this, args);
}; };
commands.forEach(function (fullCommand) { commands.forEach(function (fullCommand) {
@@ -1077,6 +1074,7 @@ Multi.prototype.exec_transaction = function (callback) {
var cb; var cb;
this.errors = []; this.errors = [];
this.callback = callback; this.callback = callback;
this._client.stream.cork();
this._client.pipeline = len + 2; this._client.pipeline = len + 2;
this.wants_buffers = new Array(len); this.wants_buffers = new Array(len);
this.send_command('multi', []); this.send_command('multi', []);
@@ -1194,6 +1192,7 @@ Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = funct
return true; return true;
} }
this.results = new Array(len); this.results = new Array(len);
this._client.stream.cork();
this._client.pipeline = len; this._client.pipeline = len;
var lastCallback = function (cb) { var lastCallback = function (cb) {
return function (err, res) { return function (err, res) {

View File

@@ -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 () { it("returns an empty array if promisified", function () {
return client.batch().execAsync().then(function(res) { return client.batch().execAsync().then(function(res) {
assert.strictEqual(res.length, 0); assert.strictEqual(res.length, 0);

View File

@@ -73,6 +73,47 @@ describe("The 'multi' method", function () {
assert.strictEqual(notBuffering, true); 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) { it('roles back a transaction when one command in a sequence of commands fails', function (done) {
var multi1, multi2; var multi1, multi2;
var expected = helper.serverVersionAtLeast(client, [2, 6, 5]) ? helper.isError() : function () {}; var expected = helper.serverVersionAtLeast(client, [2, 6, 5]) ? helper.isError() : function () {};