Skip to content

Commit

Permalink
Fix #8 - emit clientError events
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-marcacci committed Sep 10, 2015
1 parent 40b4098 commit 95cd023
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 57 deletions.
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Configuration
-------------
Redlock can use [node redis](https://github.com/mranney/node_redis), [ioredis](https://github.com/luin/ioredis) or any other compatible redis library to keep its client connections.

A redlock object is instantiated with an array of at least one redis client and an optional`options` object. Properties of the Redlock object should NOT be changed after it is firstused, as doing so could have unintended consequences for live locks.
A redlock object is instantiated with an array of at least one redis client and an optional `options` object. Properties of the Redlock object should NOT be changed after it is firstused, as doing so could have unintended consequences for live locks.

```js
var client1 = require('redis').createClient(6379, 'redis1.example.com');
Expand All @@ -39,18 +39,36 @@ var redlock = new Redlock(
// the expected clock drift; for more details
// see http://redis.io/topics/distlock
driftFactor: 0.01,

// the max number of times Redlock will attempt
// to lock a resource before erroring
retryCount: 3,

// the time in ms between attempts
retryDelay: 200
}
);
```


Error Handling
--------------

Because redlock is designed for high availability, it does not care if a minority of redis instances/clusters fail at an operation. If you want to write logs or take another action when a redis client fails, you can listen for the `clientError` event:

```js

// ...

redlock.on('clientError', function(err) {
console.error('A redis error has occurred:', err);
});

// ...

```


Usage (promise style)
---------------------

Expand Down Expand Up @@ -170,7 +188,7 @@ redlock.lock(resource, ttl, function(err, lock) {
if(err) {
// ...
}

// we have the lock
else {

Expand All @@ -195,7 +213,7 @@ redlock.lock('locks:account:322456', 1000, function(err, lock) {
if(err) {
// ...
}

// we have the lock
else {

Expand Down
15 changes: 11 additions & 4 deletions redlock.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict';

var util = require('util');
var Promise = require('bluebird');
var util = require('util');
var Promise = require('bluebird');
var EventEmitter = require('events');

// constants
var unlockScript = 'if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end';
Expand Down Expand Up @@ -71,13 +72,17 @@ function Redlock(clients, options) {
this.driftFactor = typeof options.driftFactor === 'number' ? options.driftFactor : defaults.driftFactor;
this.retryCount = typeof options.retryCount === 'number' ? options.retryCount : defaults.retryCount;
this.retryDelay = typeof options.retryDelay === 'number' ? options.retryDelay : defaults.retryDelay;

// set the redis servers from additional arguments
this.servers = clients;
if(this.servers.length === 0)
throw new Error('Redlock must be instantiated with at least one redis server.');
}

// Inherit all the EventEmitter methods, like `on`, and `off`
util.inherits(Redlock, EventEmitter);

This comment has been minimized.

Copy link
@jperl

jperl Sep 11, 2015

Getting Uncaught exception TypeError: Object prototype may only be an Object or null

I20150910-20:04:12.307(-4)? at Function.create (native)
I20150910-20:04:12.307(-4)? at Object.exports.inherits (util.js:556:27)
I20150910-20:04:12.307(-4)? at Object. (/Users/jperl/dev/dispatch/meteor-cache/.meteor/local/isopacks/dispatch_cache-crud/npm/node_modules/redlock/redlock.js:83:6)

This comment has been minimized.

Copy link
@mike-marcacci

mike-marcacci Sep 11, 2015

Author Owner

Hmmm, this is interesting. I only test redlock in node v0.12 and v4.0 now, but I see that they made breaking changes to the "events" standard library since v0.10, which is what I assume you're running. I'll get this fixed and add v0.10 to travis.

This comment has been minimized.

Copy link
@mike-marcacci

mike-marcacci Sep 11, 2015

Author Owner

Fix is out and passing on v0.10.x. Note that I bumped the version to 1.0.0 as we've been using it in production for some time now and I'd like to have the unambiguity of full semver going forward.

This comment has been minimized.

Copy link
@jperl

jperl Sep 11, 2015

Thank you!



// Attach a reference to LockError per issue #7, which allows the application to use instanceof
// to destinguish between error types.
Redlock.LockError = LockError;
Expand Down Expand Up @@ -148,6 +153,7 @@ Redlock.prototype.unlock = function unlock(lock, callback) {
});

function loop(err, response) {
if(err) self.emit('clientError', err);
if(waiting-- > 1) return;
return resolve();
}
Expand Down Expand Up @@ -215,7 +221,7 @@ Redlock.prototype.extend = function extend(lock, ttl, callback) {
Redlock.prototype._lock = function _lock(resource, value, ttl, callback) {
var self = this;
return new Promise(function(resolve, reject) {
var request;
var request;

// the number of times we have attempted this lock
var attempts = 0;
Expand Down Expand Up @@ -252,6 +258,7 @@ Redlock.prototype._lock = function _lock(resource, value, ttl, callback) {
var waiting = self.servers.length;

function loop(err, response) {
if(err) self.emit('clientError', err);
if(response) votes++;
if(waiting-- > 1) return;

Expand Down

0 comments on commit 95cd023

Please sign in to comment.