Skip to content

Commit fa4f0e0

Browse files
author
Ruben Bridgewater
committed
Add monitor transaction warning / error
1 parent 286302d commit fa4f0e0

File tree

3 files changed

+58
-8
lines changed

3 files changed

+58
-8
lines changed

lib/individualCommands.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,9 @@ Multi.prototype.monitor = Multi.prototype.MONITOR = function monitor (callback)
7171
this.queue.push(['monitor', [], monitor_callback(this._client, callback)]);
7272
return this;
7373
}
74-
var err = new Error(
75-
'You used the monitor command in combination with a transaction. Due to faulty return values of ' +
76-
'Redis in this context, the monitor command is now executed without transaction instead and ignored ' +
77-
'in the multi statement.'
78-
);
79-
err.command = 'MONITOR';
80-
utils.reply_in_order(this._client, callback, err);
81-
this._client.monitor('monitor', callback);
74+
// Set multi monitoring to indicate the exec that it should abort
75+
// Remove this "hack" as soon as Redis might fix this
76+
this.monitoring = true;
8277
return this;
8378
};
8479

lib/multi.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ function multi_callback (self, err, replies) {
8585
}
8686

8787
Multi.prototype.exec_transaction = function exec_transaction (callback) {
88+
if (this.monitoring || this._client.monitoring) {
89+
var err = new Error(
90+
'Using transaction with a client that is in monitor mode does not work due to faulty return values of Redis.'
91+
);
92+
err.command = 'EXEC';
93+
err.code = 'EXECABORT';
94+
return utils.reply_in_order(this._client, callback, err);
95+
}
8896
var self = this;
8997
var len = self.queue.length;
9098
self.errors = [];

test/multi.spec.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
var assert = require('assert');
44
var config = require('./lib/config');
55
var helper = require('./helper');
6+
var utils = require('../lib/utils');
67
var redis = config.redis;
78
var zlib = require('zlib');
89
var client;
@@ -129,6 +130,52 @@ describe("The 'multi' method", function () {
129130
client = redis.createClient.apply(null, args);
130131
});
131132

133+
describe('monitor and transactions do not work together', function () {
134+
135+
it('results in a execabort', function (done) {
136+
// Check that transactions in combination with monitor result in an error
137+
client.monitor(function (e) {
138+
var multi = client.multi();
139+
multi.set('hello', 'world');
140+
multi.exec();
141+
client.on('error', function (err) {
142+
assert.strictEqual(err.code, 'EXECABORT');
143+
done(e);
144+
});
145+
});
146+
});
147+
148+
it('results in a execabort #2', function (done) {
149+
// Check that using monitor with a transactions results in an error
150+
client.multi().monitor().set('foo', 'bar').exec(function (err, res) {
151+
assert.strictEqual(err.code, 'EXECABORT');
152+
done();
153+
});
154+
});
155+
156+
it('sanity check', function (done) {
157+
// Check if Redis still has the error
158+
client.monitor();
159+
client.send_command('multi');
160+
client.send_command('set', ['foo', 'bar']);
161+
client.send_command('get', ['foo']);
162+
client.send_command('exec', function (err, res) {
163+
// res[0] is going to be the monitor result of set
164+
// res[1] is going to be the result of the set command
165+
assert(utils.monitor_regex.test(res[0]));
166+
assert.strictEqual(res[1], 'OK');
167+
assert.strictEqual(res.length, 2);
168+
});
169+
// Remove the listener and add it back again after the error
170+
var mochaListener = helper.removeMochaListener();
171+
process.on('uncaughtException', function (err) {
172+
helper.removeMochaListener();
173+
process.on('uncaughtException', mochaListener);
174+
done();
175+
});
176+
});
177+
});
178+
132179
it('executes a pipelined multi properly in combination with the offline queue', function (done) {
133180
var multi1 = client.multi();
134181
multi1.set('m1', '123');

0 commit comments

Comments
 (0)