<commit_before>![redislock](http://danielstjules.com/github/redislock-logo.png)

Node distributed locking using redis with lua scripts. Compatible with
redis >= 2.6.12. A better alternative to locking strategies based on SETNX or
WATCH/MULTI. Refer to [Implementation](#implementation) and
[Alternatives](#alternatives) for details.

[![Build Status](https://travis-ci.org/danielstjules/redislock.png)](https://travis-ci.org/danielstjules/redislock)

* [Installation](#installation)
* [Overview](#overview)
* [Implementation](#implementation)
* [Alternatives](#alternatives)
* [API](#api)
    * [redislock.createLock(client, \[options\])](#redislockcreatelockclient-options)
    * [redislock.setDefaults(options)](#redislocksetdefaultsoptions)
    * [redislock.getAcquiredLocks()](#redislockgetacquiredlocks)
    * [redislock.LockAcquisitionError](#redislocklockacquisitionerror)
    * [redislock.LockReleaseError](#redislocklockreleaseerror)
    * [redislock.LockExtendError](#redislocklockextenderror)
* [Class: Lock](#class-lock)
    * [lock.acquire(key, \[fn\])](#lockacquirekey-fn)
    * [lock.release(\[fn\])](#lockreleasefn)
    * [lock.extend(key, \[fn\])](#lockextendtime-fn)
* [Tests](#tests)

## Installation

Using npm, you can install redislock with `npm install --save redislock`.
You can also require it as a dependency in your `package.json` file:

```
"dependencies": {
    "redislock": "*"
}
```

## Overview

redislock offers both atomic acquire and release operations, avoiding race
conditions among clients, as well as the need for lock-specific redis
connections. Lock creation requires a node_redis client, and accepts an
object specifying the following three options:

 * timeout: Time in milliseconds before which a lock expires (default: 10000 ms)
 * retries: Maximum number of retries in acquiring a lock if the first attempt failed (default: 0, infinite: -1)
 * delay:   Time in milliseconds to wait between each attempt (default: 50 ms)

``` javascript
var client = require('redis').createClient();
var lock   = require('redislock').createLock(client, {
  timeout: 20000,
  retries: 3,
  delay: 100
});

lock.acquire('app:feature:lock', function(err) {
  // if (err) ... Failed to acquire the lock

  lock.release(function(err) {
    // if (err) ... Failed to release
  });
});
```

Supports promises, thanks to bluebird, out of the box:

``` javascript
var client = require('redis').createClient();
var lock   = require('redislock').createLock(client);

var LockAcquisitionError = redislock.LockAcquisitionError;
var LockReleaseError     = redislock.LockReleaseError;

lock.acquire('app:feature:lock').then(function() {
  // Lock has been acquired
  return lock.release();
}).then(function() {
  // Lock has been released
}).catch(LockAcquisitionError, function(err) {
  // The lock could not be acquired
}).catch(LockReleaseError, function(err) {
  // The lock could not be released
});
```

And an example with co:

``` javascript
var co     = require('co');
var client = require('redis').createClient();
var lock   = require('redislock').createLock(client);

co(function *(){
  try {<commit_msg>Readme example not working<commit_after>![redislock](http://danielstjules.com/github/redislock-logo.png)

Node distributed locking using redis with lua scripts. Compatible with
redis >= 2.6.12. A better alternative to locking strategies based on SETNX or
WATCH/MULTI. Refer to [Implementation](#implementation) and
[Alternatives](#alternatives) for details.

[![Build Status](https://travis-ci.org/danielstjules/redislock.png)](https://travis-ci.org/danielstjules/redislock)

* [Installation](#installation)
* [Overview](#overview)
* [Implementation](#implementation)
* [Alternatives](#alternatives)
* [API](#api)
    * [redislock.createLock(client, \[options\])](#redislockcreatelockclient-options)
    * [redislock.setDefaults(options)](#redislocksetdefaultsoptions)
    * [redislock.getAcquiredLocks()](#redislockgetacquiredlocks)
    * [redislock.LockAcquisitionError](#redislocklockacquisitionerror)
    * [redislock.LockReleaseError](#redislocklockreleaseerror)
    * [redislock.LockExtendError](#redislocklockextenderror)
* [Class: Lock](#class-lock)
    * [lock.acquire(key, \[fn\])](#lockacquirekey-fn)
    * [lock.release(\[fn\])](#lockreleasefn)
    * [lock.extend(key, \[fn\])](#lockextendtime-fn)
* [Tests](#tests)

## Installation

Using npm, you can install redislock with `npm install --save redislock`.
You can also require it as a dependency in your `package.json` file:

```
"dependencies": {
    "redislock": "*"
}
```

## Overview

redislock offers both atomic acquire and release operations, avoiding race
conditions among clients, as well as the need for lock-specific redis
connections. Lock creation requires a node_redis client, and accepts an
object specifying the following three options:

 * timeout: Time in milliseconds before which a lock expires (default: 10000 ms)
 * retries: Maximum number of retries in acquiring a lock if the first attempt failed (default: 0, infinite: -1)
 * delay:   Time in milliseconds to wait between each attempt (default: 50 ms)

``` javascript
var client = require('redis').createClient();
var lock   = require('redislock').createLock(client, {
  timeout: 20000,
  retries: 3,
  delay: 100
});

lock.acquire('app:feature:lock', function(err) {
  // if (err) ... Failed to acquire the lock

  lock.release(function(err) {
    // if (err) ... Failed to release
  });
});
```

Supports promises, thanks to bluebird, out of the box:

``` javascript
var client    = require('redis').createClient();
var redislock = require('redislock');
var lock      = redislock.createLock(client);

var LockAcquisitionError = redislock.LockAcquisitionError;
var LockReleaseError     = redislock.LockReleaseError;

lock.acquire('app:feature:lock').then(function() {
  // Lock has been acquired
  return lock.release();
}).then(function() {
  // Lock has been released
}).catch(LockAcquisitionError, function(err) {
  // The lock could not be acquired
}).catch(LockReleaseError, function(err) {
  // The lock could not be released
});
```

And an example with co:

``` javascript
var co     = require('co');
var client = require('redis').createClient();
var lock   = require('redislock').createLock(client);

co(function *(){
  try {
{'fraction_non_alphanumeric': 0.13963821009203428, 'fraction_numerical': 0.006981910504601714, 'mean_word_length': 5.095744680851064, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7331308', 'n_tokens_mistral': 2062, 'n_tokens_neox': 1887, 'n_words': 514}