diff --git a/README.md b/README.md index 10f0c044886..0975fe211e0 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,7 @@ using unix sockets if possible to increase throughput. | detect_buffers | false | If set to `true`, then replies will be sent to callbacks as Buffers. This option lets you switch between Buffers and Strings on a per-command basis, whereas `return_buffers` applies to every command on a client. **Note**: This doesn't work properly with the pubsub mode. A subscriber has to either always return Strings or Buffers. | | socket_keepalive | true | If set to `true`, the keep-alive functionality is enabled on the underlying socket. | | socket_initial_delay | 0 | Initial Delay in milliseconds, and this will also behave the interval keep alive message sending to Redis. | +| socket_timeout | 0 | If set to `0` never timeout the underlying socket connection once connected. Otherwise a time in ms to timeout if the underlying socket is idle. | | no_ready_check | false | When a connection is established to the Redis server, the server might still be loading the database from disk. While loading, the server will not respond to any commands. To work around this, Node Redis has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command indicates whether the server is ready for more commands. When ready, `node_redis` emits a `ready` event. Setting `no_ready_check` to `true` will inhibit this check. | | enable_offline_queue | true | By default, if there is no active connection to the Redis server, commands are added to a queue and are executed once the connection has been established. Setting `enable_offline_queue` to `false` will disable this feature and the callback will be executed immediately with an error, or an error will be emitted if no callback is specified. | | retry_unfulfilled_commands | false | If set to `true`, all commands that were unfulfilled while the connection is lost will be retried after the connection has been reestablished. Use this with caution if you use state altering commands (e.g. `incr`). This is especially useful if you use blocking commands. | diff --git a/index.js b/index.js index fe79c5f3935..e9b88cd7dab 100644 --- a/index.js +++ b/index.js @@ -79,6 +79,9 @@ function RedisClient (options, stream) { options.socket_initial_delay = 0; // set default to 0, which is aligned to https://nodejs.org/api/net.html#net_socket_setkeepalive_enable_initialdelay } + if (options.socket_timeout === undefined) { + options.socket_timeout = 0; + } for (var command in options.rename_commands) { options.rename_commands[command.toLowerCase()] = options.rename_commands[command]; } @@ -353,7 +356,14 @@ RedisClient.prototype.on_connect = function () { this.ready = false; this.emitted_end = false; this.stream.setKeepAlive(this.options.socket_keepalive, this.options.socket_initial_delay); - this.stream.setTimeout(0); + this.stream.setKeepAlive(this.options.socket_keepalive, this.options.socket_initialdelay); + if (this.options.socket_timeout === 0) { + this.stream.setTimeout(0); + } else { + this.stream.setTimeout(this.options.socket_timeout, function () { + this.connection_gone('timeout'); + }); + } this.emit('connect'); this.initialize_retry_vars(); diff --git a/test/connection.spec.js b/test/connection.spec.js index 827ff69c8aa..7c2d14cabc6 100644 --- a/test/connection.spec.js +++ b/test/connection.spec.js @@ -349,7 +349,7 @@ describe('connection tests', function () { }); }); - it('clears the socket timeout after a connection has been established', function (done) { + it('clears connect_timeout on the socket timeout after a connection has been established', function (done) { client = redis.createClient({ connect_timeout: 1000 }); @@ -375,6 +375,29 @@ describe('connection tests', function () { }); }); + it('set the timeout to socket_timeout after a connection has been established', function (done) { + client = redis.createClient({ + connect_timeout: 1000, + socket_timeout: 2000 + }); + process.nextTick(function () { + // node > 6 + var timeout = client.stream.timeout; + // node <= 6 + if (timeout === undefined) timeout = client.stream._idleTimeout; + assert.strictEqual(timeout, 1000); + }); + client.on('connect', function () { + // node > 6 + var timeout = client.stream.timeout; + // node <= 6 + if (timeout === undefined) timeout = client.stream._idleTimeout; + assert.strictEqual(timeout, 2000); + assert.strictEqual(client.stream.listeners('timeout').length, 1); + client.on('ready', done); + }); + }); + it('connect with host and port provided in the options object', function (done) { client = redis.createClient({ host: 'localhost',