Skip to content

Instantly share code, notes, and snippets.

@mstaicu
Last active September 12, 2020 11:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mstaicu/e9c99f62f03b771cc6b25d11050e741a to your computer and use it in GitHub Desktop.
Save mstaicu/e9c99f62f03b771cc6b25d11050e741a to your computer and use it in GitHub Desktop.
@nybblr inspired semaphore solution for limiting concurrent execution
/**
* OOP paradigm
*/
class Semaphore {
constructor(max) {
this.tasks = [];
this.counter = max;
this.dispatch = this.dispatch.bind(this);
}
dispatch() {
if (this.counter > 0 && this.tasks.length > 0) {
this.counter--;
this.tasks.shift()();
}
}
release() {
this.counter++;
this.dispatch();
}
acquire() {
return new Promise(res => {
this.tasks.push(res);
setTimeout(this.dispatch, 100);
});
}
}
var semaphore = new Semaphore(2);
var run = (async() => {
await semaphore.acquire();
console.log('first runner');
await semaphore.acquire();
console.log('second runner');
await semaphore.acquire();
console.log('third runner');
})();
/**
* FP paradigm
*/
let Semaphore = max => {
let tasks = [];
let counter = max;
let dispatch = () => {
if (counter > 0 && tasks.length > 0) {
counter--;
tasks.shift()();
}
};
let release = () => {
counter++;
dispatch();
};
let acquire = () =>
new Promise(res => {
tasks.push(res);
/**
* Adjust for desired platform
*/
setTimeout(dispatch);
});
return async fn => {
await acquire();
let result;
try {
result = await fn();
} catch (e) {
throw e;
} finally {
release();
}
return result;
};
};
let semaphore = Semaphore(2);
let run = (async () => {
let result = await semaphore(async () => {
return await Promise.resolve(1);
});
return result;
})();
/**
* Limit
*/
var limit = (max, fn) => {
var semaphore = Semaphore(2);
return (...args) => semaphore(() => fn(...args));
};
var doStuff = data =>
new Promise(res =>
setTimeout(
() => {
console.log(data);
res();
},
1000,
data
)
);
var limitStuffToDo = limit(2, doStuff);
limitStuffToDo("one");
limitStuffToDo("two");
limitStuffToDo("3");
limitStuffToDo("four");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment