Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

async-lock

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

async-lock - npm Package Compare versions

Comparing version 0.1.2 to 0.2.0

5

History.md

@@ -0,3 +1,8 @@

0.2.0 / 2015-02-21
==================
* Support promise mode
* Pending task limit
0.1.0 / 2015-01-13
==================
* Initial version

70

lib/index.js
'use strict';
var Q = require('q');
var AsyncLock = function(opts){

@@ -11,5 +13,7 @@ opts = opts || {};

this.timeout = opts.timeout || AsyncLock.DEFAULT_TIMEOUT;
this.maxPending = opts.maxPending || AsyncLock.DEFAULT_MAX_PENDING;
};
AsyncLock.DEFAULT_TIMEOUT = 2000;
AsyncLock.DEFAULT_TIMEOUT = 10 * 1000;
AsyncLock.DEFAULT_MAX_PENDING = 1000;

@@ -21,3 +25,3 @@ /**

* @param {function} fn async function
* @param {function} cb (optional) callback function
* @param {function} cb (optional) callback function, otherwise will return a promise
* @param {Object} opts (optional) options

@@ -30,2 +34,15 @@ */

if(typeof(fn) !== 'function'){
throw new Error('You must pass a function to execute');
}
var deferred = null;
if(typeof(cb) !== 'function'){
opts = cb;
cb = null;
// will return a promise
deferred = Q.defer();
}
opts = opts || {};

@@ -37,3 +54,3 @@

var done = function(){
var done = function(err, ret){
// Make sure done is only called once

@@ -51,6 +68,17 @@ if(finished){

//callback
if(typeof(cb) === 'function'){
cb.apply(null, arguments);
//callback mode
if(!deferred){
if(typeof(cb) === 'function'){
cb.apply(null, arguments);
}
}
else{
//promise mode
if(err){
deferred.reject(err);
}
else{
deferred.resolve(ret);
}
}

@@ -64,4 +92,19 @@ //run next func

var exec = function(){
timer = setTimeout(done.bind(null, new Error('async-lock timed out')), opts.timeout ? opts.timeout : self.timeout);
fn(done);
var timeout = opts.timeout ? opts.timeout : self.timeout;
timer = setTimeout(done.bind(null, new Error('async-lock timed out')), timeout);
// Callback mode
if(fn.length === 1){
fn(done);
}
else{
// Promise mode
Q.fcall(function(){
return fn();
}).then(function(ret){
done(null, ret);
}, function(err){
done(err);
});
}
};

@@ -74,4 +117,13 @@

else{
this.queues[key].push(exec);
if(this.queues[key].length >= this.maxPending){
done(new Error('Too much pending tasks'));
}
else{
this.queues[key].push(exec);
}
}
if(deferred){
return deferred.promise;
}
};

@@ -78,0 +130,0 @@

5

package.json
{
"name": "async-lock",
"description": "",
"version": "0.1.2",
"version": "0.2.0",
"author": "rain1017",

@@ -29,3 +29,4 @@ "private" : false,

"dependencies": {
"q": "~1.1.2",
"lodash": "~3.2.0"
},

@@ -32,0 +33,0 @@ "devDependencies": {

@@ -17,8 +17,23 @@ # async-lock

* @param {function} fn async function with node.js style
* @param {function} cb (optional) callback function
* @param {function} cb (optional) callback function, otherwise will return a promise
* @param {Object} opts (optional) options
*/
lock.acquire(key, fn, cb, opts);
lock.acquire(key, function(done){
// async work
done(err, ret);
}, function(err, ret){
// lock released
}, opts);
```
## Promise mode
```
lock.acquire(key, function(){
// return value or promise
}).then(function(){
// lock released
});
```
## Acquire multiple keys

@@ -30,21 +45,25 @@

## Specify timeout
## Options
```
// Specify timeout
var lock = new AsyncLock({timeout : 5000});
lock.acquire(key, fn, function(err){
lock.acquire(key, fn, cb, function(err, ret){
// timed out error will be returned here if fn has not return within given time
});
//Specify timeout for one function
// Specify timeout for one function
lock.acquire(key, fn, cb, {timeout : 5000});
```
## Get running state
// Set max pending tasks
var lock = new AsyncLock({maxPending : 1000});
lock.acquire(key, fn, cb, function(err, ret){
// Handle too much pending error
})
```
// Where there is any running or pending async function
// Whether there is any running or pending async function
lock.isBusy();
```
## License

@@ -51,0 +70,0 @@ (The MIT License)

'use strict';
var Q = require('q');
var _ = require('lodash');
var AsyncLock = require('../index.js');
var assert = require('assert');
Q.longStackSupport = true;
describe('AsyncLock Tests', function(){

@@ -123,2 +127,54 @@ it('Single key test', function(done){

});
it('Promise mode', function(done){
var lock = new AsyncLock();
var value = 0;
var concurrency = 8;
Q.all(_.range(concurrency).map(function(){
return lock.acquire('key', function(){
var tmp = null;
// Simulate non-atomic check and set
return Q() // jshint ignore:line
.delay(_.random(10))
.then(function(){
tmp = value;
})
.delay(_.random(20))
.then(function(){
value = tmp + 1;
});
});
})).then(function(){
assert(value === concurrency);
done();
}, function(err){
done(err);
});
});
it('Error handling', function(done){
var lock = new AsyncLock();
lock.acquire('key', function(){
throw new Error('error');
}).catch(function(e){
assert(e.message === 'error');
done();
});
});
it('Too much pending', function(done){
var lock = new AsyncLock({maxPending : 1});
lock.acquire('key', function(){
return Q().delay(20); // jshint ignore:line
});
lock.acquire('key', function(){
return Q().delay(20); // jshint ignore:line
});
lock.acquire('key', function(){})
.catch(function(e){
done();
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc