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

Add socket_nodelay option to control Nagle. Fixes [GH-33]

This commit is contained in:
Matt Ranney
2011-11-16 11:12:26 -10:00
parent bf806a0be3
commit b9734d13eb
3 changed files with 67 additions and 6 deletions

View File

@@ -171,12 +171,16 @@ port and host are probably fine. `options` in an object with the following poss
* `parser`: which Redis protocol reply parser to use. Defaults to `hiredis` if that module is installed. * `parser`: which Redis protocol reply parser to use. Defaults to `hiredis` if that module is installed.
This may also be set to `javascript`. This may also be set to `javascript`.
* `return_buffers`: defaults to false. If set to `true`, then all replies will be sent to callbacks as node Buffer * `return_buffers`: defaults to `false`. If set to `true`, then all replies will be sent to callbacks as node Buffer
objects instead of JavaScript Strings. objects instead of JavaScript Strings.
* `detect_buffers`: default to false. If set to `true`, then replies will be sent to callbacks as node Buffer objects * `detect_buffers`: default to `false`. If set to `true`, then replies will be sent to callbacks as node Buffer objects
if any of the input arguments to the original command were Buffer objects. if any of the input arguments to the original command were Buffer objects.
This option lets you switch between Buffers and Strings on a per-command basis, whereas `return_buffers` applies to This option lets you switch between Buffers and Strings on a per-command basis, whereas `return_buffers` applies to
every command on a client. every command on a client.
* `socket_nodelay`: defaults to `true`. Whether to call setNoDelay() on the TCP stream, which disables the
Nagle algorithm on the underlying socket. Setting this option to `false` can result in additional throughput at the
cost of more latency. Most applications will want this set to `true`.
var redis = require("redis"), var redis = require("redis"),
client = redis.createClient(null, null, {detect_buffers: true}); client = redis.createClient(null, null, {detect_buffers: true});

View File

@@ -33,6 +33,9 @@ function RedisClient(stream, options) {
this.connected = false; this.connected = false;
this.ready = false; this.ready = false;
this.connections = 0; this.connections = 0;
if (this.options.socket_nodelay === undefined) {
this.options.socket_nodelay = true;
}
this.should_buffer = false; this.should_buffer = false;
this.command_queue_high_water = this.options.command_queue_high_water || 1000; this.command_queue_high_water = this.options.command_queue_high_water || 1000;
this.command_queue_low_water = this.options.command_queue_low_water || 0; this.command_queue_low_water = this.options.command_queue_low_water || 0;
@@ -200,7 +203,9 @@ RedisClient.prototype.on_connect = function () {
this.command_queue = new Queue(); this.command_queue = new Queue();
this.emitted_end = false; this.emitted_end = false;
this.initialize_retry_vars(); this.initialize_retry_vars();
this.stream.setNoDelay(); if (this.options.socket_nodelay) {
this.stream.setNoDelay();
}
this.stream.setTimeout(0); this.stream.setTimeout(0);
this.init_parser(); this.init_parser();

58
test.js
View File

@@ -70,7 +70,7 @@ function require_error(label) {
}; };
} }
function is_empty_array(obj) { function is_empty_array(obj) {
return Array.isArray(obj) && obj.length === 0; return Array.isArray(obj) && obj.length === 0;
} }
@@ -396,6 +396,58 @@ tests.detect_buffers = function () {
}); });
}; };
tests.socket_nodelay = function () {
var name = "socket_nodelay", c1, c2, c3, ready_count = 0, quit_count = 0;
c1 = redis.createClient(null, null, {socket_nodelay: true});
c2 = redis.createClient(null, null, {socket_nodelay: false});
c3 = redis.createClient(null, null);
function quit_check() {
quit_count++;
if (quit_count === 3) {
next(name);
}
}
function run() {
assert.strictEqual(true, c1.options.socket_nodelay, name);
assert.strictEqual(false, c2.options.socket_nodelay, name);
assert.strictEqual(true, c3.options.socket_nodelay, name);
c1.set(["set key 1", "set val"], require_string("OK", name));
c1.set(["set key 2", "set val"], require_string("OK", name));
c1.get(["set key 1"], require_string("set val", name));
c1.get(["set key 2"], require_string("set val", name));
c2.set(["set key 3", "set val"], require_string("OK", name));
c2.set(["set key 4", "set val"], require_string("OK", name));
c2.get(["set key 3"], require_string("set val", name));
c2.get(["set key 4"], require_string("set val", name));
c3.set(["set key 5", "set val"], require_string("OK", name));
c3.set(["set key 6", "set val"], require_string("OK", name));
c3.get(["set key 5"], require_string("set val", name));
c3.get(["set key 6"], require_string("set val", name));
c1.quit(quit_check);
c2.quit(quit_check);
c3.quit(quit_check);
}
function ready_check() {
ready_count++;
if (ready_count === 3) {
run();
}
}
c1.on("ready", ready_check);
c2.on("ready", ready_check);
c3.on("ready", ready_check);
};
tests.reconnect = function () { tests.reconnect = function () {
var name = "reconnect"; var name = "reconnect";
@@ -734,7 +786,7 @@ tests.HGETALL_NULL = function () {
}; };
tests.UTF8 = function () { tests.UTF8 = function () {
var name = "UTF8", var name = "UTF8",
utf8_sample = "ಠ_ಠ"; utf8_sample = "ಠ_ಠ";
client.set(["utf8test", utf8_sample], require_string("OK", name)); client.set(["utf8test", utf8_sample], require_string("OK", name));
@@ -859,7 +911,7 @@ tests.SDIFFSTORE = function () {
client.sadd('baz', 'a', require_number(1, name)); client.sadd('baz', 'a', require_number(1, name));
client.sadd('baz', 'd', require_number(1, name)); client.sadd('baz', 'd', require_number(1, name));
// NB: SDIFFSTORE returns the number of elements in the dstkey // NB: SDIFFSTORE returns the number of elements in the dstkey
client.sdiffstore('quux', 'foo', 'bar', 'baz', require_number(2, name)); client.sdiffstore('quux', 'foo', 'bar', 'baz', require_number(2, name));