If the key is missing, reply will be null (probably):
If the key is missing, reply will be null. Only if the [Redis Command Reference](http://redis.io/commands) states something else it will not be null.
```js
client.get("missingkey", function(err, reply) {
@ -103,15 +107,13 @@ JavaScript Array of node Buffers. `HGETALL` returns an Object with Buffers keyed
### "ready"
`client` will emit `ready` once a connection is established to the Redis server and the server reports
that it is ready to receive commands. Commands issued before the `ready` event are queued,
`client` will emit `ready` once a connection is established. Commands issued before the `ready` event are queued,
then replayed just before this event is emitted.
### "connect"
`client` will emit `connect` at the same time as it emits `ready` unless `client.options.no_ready_check`
is set. If this options is set, `connect` will be emitted when the stream is connected, and then
you are free to try to send commands.
is set. If this options is set, `connect` will be emitted when the stream is connected.
### "reconnecting"
@ -120,26 +122,9 @@ are passed an object containing `delay` (in ms) and `attempt` (the attempt #) at
### "error"
`client` will emit `error` when encountering an error connecting to the Redis server.
Note that "error" is a special event type in node. If there are no listeners for an
"error" event, node will exit. This is usually what you want, but it can lead to some
cryptic error messages like this:
mjr:~/work/node_redis (master)$ node example.js
node.js:50
throw e;
^
Error: ECONNREFUSED, Connection refused
at IOWatcher.callback (net:870:22)
at node.js:607:9
Not very useful in diagnosing the problem, but if your program isn't ready to handle this,
it is probably the right thing to just exit.
`client` will emit `error` when encountering an error connecting to the Redis server or when any other in node_redis occurs.
`client` will also emit `error` if an exception is thrown inside of `node_redis` for whatever reason.
It would be nice to distinguish these two cases.
So please attach the error listener to node_redis.
### "end"
@ -149,8 +134,7 @@ It would be nice to distinguish these two cases.
`client` will emit `drain` when the TCP connection to the Redis server has been buffering, but is now
writable. This event can be used to stream commands in to Redis and adapt to backpressure. Right now,
you need to check `client.command_queue.length` to decide when to reduce your send rate. Then you can
resume sending when you get `drain`.
you need to check `client.command_queue.length` to decide when to reduce your send rate and resume sending commands when you get `drain`.
### "idle"
@ -169,39 +153,35 @@ port and host are probably fine and you don't need to supply any arguments. `cre
`options` is an object with the following possible properties:
* `parser`: which Redis protocol reply parser to use. Defaults to `hiredis` if that module is installed.
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
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
if any of the input arguments to the original command were Buffer objects.
* `parser`: *hiredis*; Which Redis protocol reply parser to use. If `hiredis` is not installed it will fallback to `javascript`.
* `return_buffers`: *false*; If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings.
* `detect_buffers`: *false*; If set to `true`, then replies will be sent to callbacks as Buffers
if any of the input arguments to the original command were 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.
* `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`.
* `socket_keepalive`defaults to `true`. Whether the keep-alive functionality is enabled on the underlying socket.
* `no_ready_check`: defaults to `false`. When a connection is established to the Redis server, the server might still
be loading the database from disk. While loading, the server not respond to any commands. To work around this,
* `socket_nodelay`: *true*; Disables the [Nagle algorithm](https://en.wikipedia.org/wiki/Nagle%27s_algorithm).
Setting this option to `false` can result in additional throughput at the cost of more latency.
Most applications will want this set to `true`.
* `socket_keepalive`*true*; Whether the keep-alive functionality is enabled on the underlying socket.
* `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`: defaults to `true`. By default, if there is no active
* `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 execute immediately
with an error, or an error will be thrown if no callback is specified.
* `retry_max_delay`: defaults to `null`. By default every time the client tries to connect and fails time before
reconnection (delay) almost doubles. This delay normally grows infinitely, but setting `retry_max_delay` limits delay
to maximum value, provided in milliseconds.
* `connect_timeout` defaults to `86400000`. Setting `connect_timeout` limits total time for client to reconnect.
Value is provided in milliseconds and is counted once the disconnect occurred. The last retry is going to happen exactly at the timeout time.
`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_max_delay`: *null*; By default every time the client tries to connect and fails the reconnection delay almost doubles.
This delay normally grows infinitely, but setting `retry_max_delay` limits it to the maximum value, provided in milliseconds.
* `connect_timeout`*86400000*; Setting `connect_timeout` limits total time for client to reconnect.
The value is provided in milliseconds and is counted once the disconnect occurred. The last retry is going to happen exactly at the timeout time.
That way the default is to try reconnecting until 24h passed.
* `max_attempts`defaults to `0`. By default client will try reconnecting until connected. Setting `max_attempts`
* `max_attempts`*0*; By default client will try reconnecting until connected. Setting `max_attempts`
limits total amount of connection tries. Setting this to 1 will prevent any reconnect tries.
* `auth_pass` defaults to `null`. By default client will try connecting without auth. If set, client will run redis auth command on connect.
* `family` defaults to `IPv4`. The client connects in IPv4 if not specified or if the DNS resolution returns an IPv4 address.
You can force an IPv6 if you set the family to 'IPv6'. See nodejs net or dns modules how to use the family type.
* `auth_pass`*null*; If set, client will run redis auth command on connect.
* `family`*IPv4*; You can force using IPv6 if you set the family to 'IPv6'. See Node.js [net](https://nodejs.org/api/net.html) or [dns](https://nodejs.org/api/dns.html) modules how to use the family type.
```js
var redis = require("redis"),
@ -221,11 +201,9 @@ client.get(new Buffer("foo_rand000000000000"), function (err, reply) {
client.end();
```
## client.auth(password, callback)
When connecting to Redis servers that require authentication, the `AUTH` command must be sent as the
When connecting to a Redis server that requires authentication, the `AUTH` command must be sent as the
first command after connecting. This can be tricky to coordinate with reconnections, the ready check,
etc. To make this easier, `client.auth()` stashes `password` and will send it after each connection,
including reconnections. `callback` is invoked only once, after the response to the very first
@ -247,10 +225,11 @@ var redis = require("redis"),
client.end(); // No further commands will be processed
client.get("foo_rand000000000000", function (err, reply) {
console.log(reply.toString());
// This won't be called anymore
console.log(err);
});
client.end();
```
`client.end()` is useful for timeout cases where something is stuck or taking too long and you want
@ -436,10 +415,8 @@ client.multi()
same command methods as `client` objects do. Commands are queued up inside the `Multi` object
until `Multi.exec()` is invoked.
The `callback` of `.exec()` will get invoked with two arguments:
* `err`**type:**`null | Array` err is either null or an array of Error Objects corresponding the the sequence the commands where chained. The last item of the array will always be an `EXECABORT` type of error originating from the `.exec()` itself.
* `results`**type:**`null | Array` results is an array of responses corresponding the the sequence the commands where chained.
If your code contains an syntax error an EXECABORT error is going to be thrown and all commands are going to be aborted. That error contains a `.errors` property that contains the concret errors.
If all commands were queued successfully and an error is thrown by redis while processing the commands that error is going to be returned in the result array! No other command is going to be aborted though than the onces failing.
You can either chain together `MULTI` commands as in the above example, or you can queue individual
commands while still sending regular client command as in this example:
@ -484,7 +461,6 @@ client.multi([
});
```
## Monitor mode
Redis supports the `MONITOR` command, which lets you see all commands received by the Redis server
@ -561,7 +537,7 @@ Used internally to send commands to Redis. Nearly all Redis commands have been a
However, if new commands are introduced before this library is updated, you can use `send_command()` to send arbitrary commands to Redis.
The command has to be lower case.
All commands are sent as multi-bulk commands. `args` can either be an Array of arguments, or omitted.
All commands are sent as multi-bulk commands. `args` can either be an Array of arguments, or omitted / set to undefined.
## client.connected
@ -623,119 +599,62 @@ Much effort has been spent to make `node_redis` as fast as possible for common
operations. As pipelining happens naturally from shared connections, overall
efficiency goes up.
Here are typical results of `multi_bench.js` which is similar to
`redis-benchmark` from the Redis distribution. It uses 5 concurrent connections
and shows the difference between pipelines of 1 and 50.
To get debug output run your `node_redis` application with `NODE_DEBUG=redis`.
## TODO
1. 100% coverage
2. More performance improvements
3. Stream large set/get values into and out of Redis. Otherwise the entire value must be in node's memory.
4. Performance can be better for very large values in the js parser.
## How to Contribute
- open a pull request and then wait for feedback
- Open a pull request or an issue about what you want to implement / change. We're glad for any help!
## Contributors
Many people have have added features and fixed bugs in `node_redis`. Thanks to all of them!
Many [people](https://github.com/NodeRedis/node_redis/graphs/contributors) have have added features and fixed bugs in `node_redis`. Thanks to all of them!
## LICENSE - "MIT License"
Copyright (c) 2015 Matthew Ranney, http://ranney.com/
Copyright (c) by NodeRedis
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@ -757,3 +676,5 @@ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Originally developed by Matthew Ranney, http://ranney.com/
* [#815](https://github.com/NodeRedis/node_redis/pull/815) Consistently use new debug functionality (@BridgeAR)
* [#814](https://github.com/NodeRedis/node_redis/pull/814) Support new commands and drop support for deprecated 'substr' (@BridgeAR)
## v2.0.0 - Sep 21, 2015
This is the biggest release that node_redis had since it was released in 2010. A long list of outstanding bugs has been fixed, so we are very happy to present you redis 2.0 and we highly recommend updating as soon as possible.
#What's new in 2.0
- Implemented a "connection is broken" mode if no connection could be established
- node_redis no longer throws under any circumstances, preventing it from terminating applications.
- Multi error handling is now working properly
- Consistent command behavior including multi
- Windows support
- Improved performance
- A lot of code cleanup
- Many bug fixes
- Better user support!
## Features:
- Added a "redis connection is broken" mode after reaching max connection attempts / exceeding connection timeout. (@BridgeAR)
- Added NODE_DEBUG=redis env to activate the debug_mode (@BridgeAR)
- Added a default connection timeout of 24h instead of never timing out as a default (@BridgeAR)
- Added: Network errors and other stream errors will from now on include the error code as `err.code` property (@BridgeAR)
- Added: Errors thrown by redis will now include the redis error code as `err.code` property. (@skeggse &@BridgeAR)
- Added: Errors thrown by node_redis will now include a `err.command` property for the command used (@BridgeAR)
- Added new commands and drop support for deprecated *substr* (@BridgeAR)
- Added new possibilities how to provide the command arguments (@BridgeAR)
- The entries in the keyspace of the server_info is now an object instead of a string. (@SinisterLight &@BridgeAR)
- Small speedup here and there (e.g. by not using .toLowerCase() anymore) (@BridgeAR)
- Full windows support (@bcoe)
- Increased coverage by 10% and add a lot of tests to make sure everything works as it should. We now reached 97% :-) (@BridgeAR)
- Remove dead code, clean up and refactor very old chunks (@BridgeAR)
- Don't flush the offline queue if reconnecting (@BridgeAR)
- Emit all errors insteaf of throwing sometimes and sometimes emitting them (@BridgeAR)
- *auth_pass* passwords are now checked to be a valid password (@jcppman &@BridgeAR)
## Bug fixes:
- Don't kill the app anymore by randomly throwing errors sync instead of emitting them (@BridgeAR)
- Don't catch user errors anymore occuring in callbacks (no try callback anymore & more fixes for the parser) (@BridgeAR)
- Early garbage collection of queued items (@dohse)
- Fix js parser returning errors as strings (@BridgeAR)
- Do not wrap errors into other errors (@BridgeAR)
- Authentication failures are now returned in the callback instead of being emitted (@BridgeAR)
- Fix a memory leak on reconnect (@rahar)
- Using `send_command` directly may no also be called without the args as stated in the [README.md](./README.md) (@BridgeAR)
- Fix the multi.exec error handling (@BridgeAR)
- Fix commands being inconsistent and behaving wrong (@BridgeAR)
- Channel names with spaces are now properly resubscribed after a reconnection (@pbihler)
- Do not try to reconnect after the connection timeout has been exceeded (@BridgeAR)
- Removed bad .eval implementation (@BridgeAR)
- Fix commands not being rejected after calling .quit (@BridgeAR)
- Fix .auth calling the callback twice if already connected (@BridgeAR)
- Fix detect_buffers not working in pub sub mode and while monitoring (@BridgeAR)
- Fix channel names always being strings instead of buffers while return_buffers is true (@BridgeAR)
- Don't print any debug statements if not asked for (@BridgeAR)
- Fix a couple small other bugs
## Breaking changes:
1. redis.send_command commands have to be lower case from now on. This does only apply if you use `.send_command` directly instead of the convenient methods like `redis.command`.
2. Error messages have changed quite a bit. If you depend on a specific wording please check your application carfully.
3. Errors are from now on always either returned if a callback is present or emitted. They won't be thrown (neither sync, nor async).
4. The Multi error handling has changed a lot!
- All errors are from now on errors instead of strings (this only applied to the js parser).
- If an error occurs while queueing the commands an EXECABORT error will be returned including the failed commands as `.errors` property instead of an array with errors.
- If an error occurs while executing the commands and that command has a callback it'll return the error as first parameter (`err, undefined` instead of `null, undefined`).
- All the errors occuring while executing the commands will stay in the result value as error instance (if you used the js parser before they would have been strings). Be aware that the transaction won't be aborted if those error occurr!
- If `multi.exec` does not have a callback and an EXECABORT error occurrs, it'll emit that error instead.
5. If redis can't connect to your redis server it'll give up after a certain point of failures (either max connection attempts or connection timeout exceeded). If that is the case it'll emit an CONNECTION_BROKEN error. You'll have to initiate a new client to try again afterwards.
6. The offline queue is not flushed anymore on a reconnect. It'll stay until node_redis gives up trying to reach the server or until you close the connection.
7. Before this release node_redis catched user errors and threw them async back. This is not the case anymore! No user behavior of what so ever will be tracked or catched.
8. The keyspace of `redis.server_info` (db0...) is from now on an object instead of an string.
NodeRedis also thanks @qdb, @tobek, @cvibhagool, @frewsxcv, @davidbanham, @serv, @vitaliylag, @chrishamant, @GamingCoder and all other contributors that I may have missed for their contributions!
From now on we'll push new releases more frequently out and fix further long outstanding things and implement new features.