Gathering detailed insights and metrics for async-lock
Gathering detailed insights and metrics for async-lock
Gathering detailed insights and metrics for async-lock
Gathering detailed insights and metrics for async-lock
npm install async-lock
v1.4.1
Published on 22 Dec 2023
show queue name in errors
Published on 04 Feb 2022
v1.2.8
Published on 04 Jan 2021
allow maxPending=0
Published on 06 Dec 2020
be robust to lock names that match Object keys - simpler solution
Published on 12 May 2020
be robust to lock names that match Object keys
Published on 11 May 2020
Module System
Unable to determine the module system for this package.
Min. Node Version
Typescript Support
Node Version
NPM Version
399 Stars
135 Commits
50 Forks
6 Watching
2 Branches
1 Contributors
Updated on 26 Nov 2024
JavaScript (100%)
Cumulative downloads
Total Downloads
Last day
-0.8%
388,062
Compared to previous day
Last week
2.8%
2,075,642
Compared to previous week
Last month
11%
8,602,304
Compared to previous month
Last year
39%
81,378,548
Compared to previous year
Lock on asynchronous code
I did not create this package. I was granted the ownership because it was no longer being maintained, and I volunteered to fix a bug. I will not do any maintenance on it other than merge PRs.
DO NOT EXPECT ME TO ADD FEATURES OR FIX BUGS. PRs WELCOME
Nodejs is single threaded, and the code execution never gets interrupted inside an event loop, so locking is unnecessary? This is true ONLY IF your critical section can be executed inside a single event loop. However, if you have any async code inside your critical section (it can be simply triggered by any I/O operation, or timer), your critical logic will across multiple event loops, therefore it's not concurrency safe!
Consider the following code
1redis.get('key', function(err, value) { 2 redis.set('key', value * 2); 3});
The above code simply multiply a redis key by 2. However, if two users run concurrently, the execution order may like this
user1: redis.get('key') -> 1
user2: redis.get('key') -> 1
user1: redis.set('key', 1 x 2) -> 2
user2: redis.set('key', 1 x 2) -> 2
Obviously it's not what you expected
With asyncLock, you can easily write your async critical section
1lock.acquire('key', function(cb) { 2 // Concurrency safe 3 redis.get('key', function(err, value) { 4 redis.set('key', value * 2, cb); 5 }); 6}, function(err, ret) { 7});
1var AsyncLock = require('async-lock'); 2var lock = new AsyncLock(); 3 4/** 5 * @param {String|Array} key resource key or keys to lock 6 * @param {function} fn execute function 7 * @param {function} cb (optional) callback function, otherwise will return a promise 8 * @param {Object} opts (optional) options 9 */ 10lock.acquire(key, function(done) { 11 // async work 12 done(err, ret); 13}, function(err, ret) { 14 // lock released 15}, opts); 16 17// Promise mode 18lock.acquire(key, function() { 19 // return value or promise 20}, opts).then(function() { 21 // lock released 22});
1// Callback mode 2lock.acquire(key, function(done) { 3 done(new Error('error')); 4}, function(err, ret) { 5 console.log(err.message) // output: error 6}); 7 8// Promise mode 9lock.acquire(key, function() { 10 throw new Error('error'); 11}).catch(function(err) { 12 console.log(err.message) // output: error 13});
1lock.acquire([key1, key2], fn, cb);
Lock is reentrant in the same domain
1var domain = require('domain'); 2var lock = new AsyncLock({domainReentrant : true}); 3 4var d = domain.create(); 5d.run(function() { 6 lock.acquire('key', function() { 7 //Enter lock 8 return lock.acquire('key', function() { 9 //Enter same lock twice 10 }); 11 }); 12});
1// Specify timeout - max amount of time an item can remain in the queue before acquiring the lock 2var lock = new AsyncLock({timeout: 5000}); 3lock.acquire(key, fn, function(err, ret) { 4 // timed out error will be returned here if lock not acquired in given time 5}); 6 7// Specify max occupation time - max amount of time allowed between entering the queue and completing execution 8var lock = new AsyncLock({maxOccupationTime: 3000}); 9lock.acquire(key, fn, function(err, ret) { 10 // occupation time exceeded error will be returned here if job not completed in given time 11}); 12 13// Specify max execution time - max amount of time allowed between acquiring the lock and completing execution 14var lock = new AsyncLock({maxExecutionTime: 3000}); 15lock.acquire(key, fn, function(err, ret) { 16 // execution time exceeded error will be returned here if job not completed in given time 17}); 18 19// Set max pending tasks - max number of tasks allowed in the queue at a time 20var lock = new AsyncLock({maxPending: 1000}); 21lock.acquire(key, fn, function(err, ret) { 22 // Handle too much pending error 23}) 24 25// Whether there is any running or pending async function 26lock.isBusy(); 27 28// Use your own promise library instead of the global Promise variable 29var lock = new AsyncLock({Promise: require('bluebird')}); // Bluebird 30var lock = new AsyncLock({Promise: require('q')}); // Q 31 32// Add a task to the front of the queue waiting for a given lock 33lock.acquire(key, fn1, cb); // runs immediately 34lock.acquire(key, fn2, cb); // added to queue 35lock.acquire(key, priorityFn, cb, {skipQueue: true}); // jumps queue and runs before fn2
See Changelog
See issue tracker.
MIT, see LICENSE
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
2 existing vulnerabilities detected
Details
Reason
Found 7/18 approved changesets -- score normalized to 3
Reason
1 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 3
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More