Skip to content

Commit

Permalink
Add unref() method to RedisClient that will call unref() on the socke…
Browse files Browse the repository at this point in the history
…t connection, allowing it to close when unused. This is experimental because it does not yet understand the Redis protocol, so subscriptions or blocking operations will not work correctly.
  • Loading branch information
brycebaril committed Oct 2, 2013
1 parent 5f125b5 commit b12c49a
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
14 changes: 14 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 12 additions & 0 deletions test-unref.js
Original file line number Diff line number Diff line change
@@ -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())
})
18 changes: 18 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit b12c49a

Please sign in to comment.