Skip to content

Commit 13635c9

Browse files
committed
Merge pull request #840 from fintura/refactor-exec
This fixes two TODOs in combination with exec
2 parents 95a2c37 + 9e2c665 commit 13635c9

File tree

1 file changed

+72
-74
lines changed

1 file changed

+72
-74
lines changed

index.js

Lines changed: 72 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -579,15 +579,17 @@ RedisClient.prototype.return_reply = function (reply) {
579579

580580
if (command_obj && !command_obj.sub_command) {
581581
if (typeof command_obj.callback === "function") {
582-
if (this.options.detect_buffers && command_obj.buffer_args === false && 'exec' !== command_obj.command) {
583-
// If detect_buffers option was specified, then the reply from the parser will be Buffers.
584-
// If this command did not use Buffer arguments, then convert the reply to Strings here.
585-
reply = reply_to_strings(reply);
586-
}
582+
if ('exec' !== command_obj.command) {
583+
if (this.options.detect_buffers && command_obj.buffer_args === false) {
584+
// If detect_buffers option was specified, then the reply from the parser will be Buffers.
585+
// If this command did not use Buffer arguments, then convert the reply to Strings here.
586+
reply = reply_to_strings(reply);
587+
}
587588

588-
// TODO - confusing and error-prone that hgetall is special cased in two places
589-
if (reply && 'hgetall' === command_obj.command) {
590-
reply = reply_to_object(reply);
589+
// TODO - confusing and error-prone that hgetall is special cased in two places
590+
if (reply && 'hgetall' === command_obj.command) {
591+
reply = reply_to_object(reply);
592+
}
591593
}
592594

593595
command_obj.callback(null, reply);
@@ -993,92 +995,88 @@ Multi.prototype.hmset = Multi.prototype.HMSET = function (key, args, callback) {
993995
return this;
994996
};
995997

998+
Multi.prototype.send_command = function (command, args, cb) {
999+
var self = this;
1000+
this._client.send_command(command, args, function (err, reply) {
1001+
if (err) {
1002+
if (cb) {
1003+
cb(err);
1004+
} else {
1005+
self.errors.push(err);
1006+
}
1007+
}
1008+
});
1009+
};
1010+
9961011
Multi.prototype.exec = Multi.prototype.EXEC = function (callback) {
9971012
var self = this;
998-
var errors = [];
999-
var wants_buffers = [];
1013+
this.errors = [];
1014+
this.callback = callback;
1015+
this.wants_buffers = new Array(this.queue.length);
10001016
// drain queue, callback will catch "QUEUED" or error
1001-
// TODO - get rid of all of these anonymous functions which are elegant but slow
1002-
this.queue.forEach(function (args, index) {
1003-
var command = args[0], obj, i, il, buffer_args;
1017+
for (var index = 0; index < this.queue.length; index++) {
1018+
var args = this.queue[index].slice();
1019+
var command = args.shift();
1020+
var cb;
10041021
if (typeof args[args.length - 1] === "function") {
1005-
args = args.slice(1, -1);
1006-
} else {
1007-
args = args.slice(1);
1022+
cb = args.pop();
10081023
}
10091024
// Keep track of who wants buffer responses:
1010-
buffer_args = false;
1011-
for (i = 0, il = args.length; i < il; i += 1) {
1025+
this.wants_buffers[index] = false;
1026+
for (var i = 0; i < args.length; i += 1) {
10121027
if (Buffer.isBuffer(args[i])) {
1013-
buffer_args = true;
1028+
this.wants_buffers[index] = true;
1029+
break;
10141030
}
10151031
}
1016-
wants_buffers.push(buffer_args);
1017-
if (args.length === 1 && Array.isArray(args[0])) {
1018-
args = args[0];
1019-
}
1020-
if (command === 'hmset' && typeof args[1] === 'object') {
1021-
obj = args.pop();
1022-
Object.keys(obj).forEach(function (key) {
1023-
args.push(key);
1024-
args.push(obj[key]);
1025-
});
1026-
}
1027-
this._client.send_command(command, args, function (err, reply) {
1028-
if (err) {
1029-
var cur = self.queue[index];
1030-
if (typeof cur[cur.length - 1] === "function") {
1031-
cur[cur.length - 1](err);
1032-
} else {
1033-
errors.push(err);
1034-
}
1035-
}
1036-
});
1037-
}, this);
1032+
this.send_command(command, args, cb);
1033+
}
10381034

1039-
// TODO - make this callback part of Multi.prototype instead of creating it each time
1040-
return this._client.send_command("exec", [], function (err, replies) {
1041-
if (err && !err.code) {
1042-
if (callback) {
1043-
errors.push(err);
1044-
callback(errors);
1045-
return;
1035+
this._client.send_command('exec', [], function(err, replies) {
1036+
self.execute_callback(err, replies);
1037+
});
1038+
};
1039+
1040+
Multi.prototype.execute_callback = function (err, replies) {
1041+
var i, reply, args;
1042+
1043+
if (err) {
1044+
if (err.code !== 'CONNECTION_BROKEN') {
1045+
if (this.callback) {
1046+
this.errors.push(err);
1047+
this.callback(this.errors);
10461048
} else {
1047-
self._client.emit('error', err);
1049+
// Exclude CONNECTION_BROKEN so that error won't be emitted twice
1050+
this._client.emit('error', err);
10481051
}
10491052
}
1053+
return;
1054+
}
10501055

1051-
var i, il, reply, to_buffer, args;
1052-
1053-
if (replies) {
1054-
for (i = 1, il = self.queue.length; i < il; i += 1) {
1055-
reply = replies[i - 1];
1056-
args = self.queue[i];
1057-
to_buffer = wants_buffers[i];
1056+
if (replies) {
1057+
for (i = 1; i < this.queue.length; i += 1) {
1058+
reply = replies[i - 1];
1059+
args = this.queue[i];
10581060

1059-
// If we asked for strings, even in detect_buffers mode, then return strings:
1060-
if (self._client.options.detect_buffers && to_buffer === false) {
1061-
replies[i - 1] = reply = reply_to_strings(reply);
1062-
}
1061+
// If we asked for strings, even in detect_buffers mode, then return strings:
1062+
if (this._client.options.detect_buffers && this.wants_buffers[i] === false) {
1063+
replies[i - 1] = reply = reply_to_strings(reply);
1064+
}
10631065

1064-
// TODO - confusing and error-prone that hgetall is special cased in two places
1065-
if (reply && args[0] === "hgetall") {
1066-
replies[i - 1] = reply = reply_to_object(reply);
1067-
}
1066+
// TODO - confusing and error-prone that hgetall is special cased in two places
1067+
if (reply && args[0] === "hgetall") {
1068+
replies[i - 1] = reply = reply_to_object(reply);
1069+
}
10681070

1069-
if (typeof args[args.length - 1] === "function") {
1070-
args[args.length - 1](null, reply);
1071-
}
1071+
if (typeof args[args.length - 1] === "function") {
1072+
args[args.length - 1](null, reply);
10721073
}
10731074
}
1075+
}
10741076

1075-
if (callback) {
1076-
callback(null, replies);
1077-
} else if (err && err.code !== 'CONNECTION_BROKEN') {
1078-
// Exclude CONNECTION_BROKEN so that error won't be emitted twice
1079-
self._client.emit('error', err);
1080-
}
1081-
});
1077+
if (this.callback) {
1078+
this.callback(null, replies);
1079+
}
10821080
};
10831081

10841082
RedisClient.prototype.multi = RedisClient.prototype.MULTI = function (args) {

0 commit comments

Comments
 (0)