-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Way to cancel pending tokens #31
Comments
Hi, Sorry I have missed this issue. Sounds really good to me. How would that work then, by throwing maybe? |
@OlliV I currently use a homegrown mini-version of Code/**
* @typedef {{ start: () => void, cancel: () => void }} Task
*/
// This is a very simplified version of https://github.com/zeit/async-sema
// But one that supports cancelling pending tokens
// can be replaced when/if this gets resolved
// https://github.com/zeit/async-sema/issues/31
class AsyncSema {
constructor (tokens = 1) {
this._tokens = tokens;
/** @type {Task[]} */
this._taskQueue = [];
}
_createTask () {
const task = { start: () => {}, cancel: () => {} };
/** @type {Promise<void>} */
const promise = new Promise((resolve, reject) => {
task.start = () => resolve();
task.cancel = () => reject(Object.assign(new Error('Task cancelled'), {
code: 'CANCELLED'
}));
});
this._taskQueue.push(task);
return promise;
}
_scheduleNextTask () {
if (this._tokens > 0) {
const nextTask = this._taskQueue.shift();
if (nextTask) {
this._tokens -= 1;
nextTask.start();
this._scheduleNextTask();
}
}
}
async acquire () {
const promise = this._createTask();
this._scheduleNextTask();
return promise;
}
release () {
this._tokens += 1;
this._scheduleNextTask();
}
async cancel () {
const toCancel = this._taskQueue.splice(0, this._taskQueue.length);
for (const task of toCancel) {
task.cancel();
}
}
} |
Cool! 👍 |
I find I have the need to do a series of concurrent tasks, with a max concurrency, but also with a max total run time. After this time, whatever hasn't finished or started can be ignored.
I propose to add a new API
Which rejects all pending
.acquire()
calls. This way I can do the followingIf accepted I can make a PR
The text was updated successfully, but these errors were encountered: