Skip to content

Instantly share code, notes, and snippets.

@Dellos7
Forked from gregkorossy/semaphore.js
Created January 31, 2019 12:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dellos7/21d139877e986a7b5eae60c54c186f19 to your computer and use it in GitHub Desktop.
Save Dellos7/21d139877e986a7b5eae60c54c186f19 to your computer and use it in GitHub Desktop.
A simple implementation of a semaphore in JS
function Semaphore(max) {
var counter = 0;
var waiting = [];
var take = function() {
if (waiting.length > 0 && counter < max){
counter++;
let promise = waiting.shift();
promise.resolve();
}
}
this.acquire = function() {
if(counter < max) {
counter++
return new Promise(resolve => {
resolve();
});
} else {
return new Promise((resolve, err) => {
waiting.push({resolve: resolve, err: err});
});
}
}
this.release = function() {
counter--;
take();
}
this.purge = function() {
let unresolved = waiting.length;
for (let i = 0; i < unresolved; i++) {
waiting[i].err('Task has been purged.');
}
counter = 0;
waiting = [];
return unresolved;
}
}
// testing the semaphore
let sema = new Semaphore(2);
async function test(id) {
console.log('queueing task', id);
try {
await sema.acquire();
console.log('running task', id);
setTimeout(() => {
sema.release();
}, 2000);
} catch (e) {
console.error(id, e);
}
}
test(1);
test(2);
test(3);
test(4);
test(5);
setTimeout(() => {
test(10);
test(11);
test(12);
}, 1500);
setTimeout(() => {
test(20);
test(21);
test(22);
}, 2700);
// PURGE TEST
// setTimeout(() => {sema.purge();}, 2200);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment