diff --git a/README.md b/README.md index b9285af50e..babf5bf4be 100644 --- a/README.md +++ b/README.md @@ -264,6 +264,26 @@ want to do this: `client.end()` is useful for timeout cases where something is stuck or taking too long and you want to start over. +## client.unref() + +Call `unref()` on the underlying socket connection to the Redis server, allowing the program to exit once no more commands are pending. + +This is an **experimental** feature, and only supports a subset of the Redis protocol. Any commands where client state is saved on the Redis server, e.g. `*SUBSCRIBE` or the blocking `BL*` commands will *NOT* work with `.unref()`. + +```js +var redis = require("redis") +var client = redis.createClient() + +/* + Calling unref() will allow this program to exit immediately after the get command finishes. Otherwise the client would hang as long as the client-server connection is alive. +*/ +client.unref() +client.get("foo", function (err, value){ + if (err) throw(err) + console.log(value) +}) +``` + ## Friendlier hash commands Most Redis commands take a single String or an Array of Strings as arguments, and replies are sent back as a single String or an Array of Strings. diff --git a/index.js b/index.js index 38606be769..7a93a58dc8 100644 --- a/index.js +++ b/index.js @@ -121,6 +121,20 @@ RedisClient.prototype.initialize_retry_vars = function () { this.attempts = 1; }; +RedisClient.prototype.unref = function () { + trace("User requesting to unref the connection"); + if (this.connected) { + trace("unref'ing the socket connection"); + this.stream.unref(); + } + else { + trace("Not connected yet, will unref later"); + this.once("connect", function () { + this.unref(); + }) + } +}; + // flush offline_queue and command_queue, erroring any items with a callback first RedisClient.prototype.flush_and_error = function (message) { var command_obj; diff --git a/test-unref.js b/test-unref.js new file mode 100644 index 0000000000..4a3cc3622d --- /dev/null +++ b/test-unref.js @@ -0,0 +1,12 @@ +var redis = require("./") +//redis.debug_mode = true +var PORT = process.argv[2] || 6379; +var HOST = process.argv[3] || '127.0.0.1'; + +var c = redis.createClient(PORT, HOST) +c.unref() +c.info(function (err, reply) { + if (err) process.exit(-1) + if (!reply.length) process.exit(-1) + process.stdout.write(reply.length.toString()) +}) \ No newline at end of file diff --git a/test.js b/test.js index 5e204bc2c7..89f67e1b34 100644 --- a/test.js +++ b/test.js @@ -10,6 +10,7 @@ var redis = require("./index"), assert = require("assert"), crypto = require("crypto"), util = require("./lib/util"), + fork = require("child_process").fork, test_db_num = 15, // this DB will be flushed and used for testing tests = {}, connected = false, @@ -2013,6 +2014,23 @@ tests.reconnectRetryMaxDelay = function() { }); }; +tests.unref = function () { + var name = "unref"; + var external = fork("./test-unref.js"); + var done = false; + external.on("close", function (code) { + assert(code == 0, "test-unref.js failed"); + done = true; + }) + setTimeout(function () { + if (!done) { + external.kill(); + } + assert(done, "test-unref.js didn't finish in time."); + next(name); + }, 100); +}; + all_tests = Object.keys(tests); all_start = new Date(); test_count = 0;