-
Notifications
You must be signed in to change notification settings - Fork 16
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
In defence of waitUntil() #9
Comments
Yep - it's a good question. Another possible API shape, based on a suggestion for IDB+Promises by @dominiccooney: requestFlag('resource', 'exclusive', async flag => {
// ... do stuff here
}); This eliminates an explicit waitUntil() and encourages writing code that holds the flag for a bounded period of time; a throw within the async callback would (usually) release. |
Yeah, I like that design. I think we discussed it for this API and @domenic wasn't a fan. I could be misremembering though. |
requestFlag('resource', 'exclusive', async flag => {
// ... do stuff here
}); I like this best as well. I'm concerned that using the name |
Re: async callback How would timeouts (via AbortController/AbortSignal) work in this case - is the callback simply never invoked, since you can listen on Is there any return value from |
Also, if we get 'async do' in ECMAScript you can write: const flag = await requestFlag(scope, mode);
flag.waitUntil(async do {
// do stuff here...
}); ... which looks remarkably similar to the "async callback" approach. |
Writing "explicit release" in terms of "async callback" requires this, I think: function requestExplicitFlag(scope, mode, ...rest) {
return new Promise(resolve => {
requestFlag(scope, mode, flag => {
// p waits until flag.release() is called
const p = new Promise(r => { flag.release = r; });
resolve(flag);
return p;
}, ...rest);
});
} |
await requestFlag('resource', 'exclusive', async flag => {
// ... do stuff here
});
console.log('Task complete!'); But it also means it can reject with |
If I had a preference, I can't remember why. It is interesting that the async callback version would maybe allow signaling aborts... |
I'm probably misremembering then, sorry! |
I think they'd all allow signalling aborts equally? const controller = new AbortController();
try {
// 1
const flag = await requestFlag(scope, mode, {signal:controller.signal});
flag.waitUntil( async_do_stuff() );
// 2
const flag = await requestFlag(scope, mode, {signal:controller.signal});
try { await async_do_stuff(); } finally { flag.release(); }
// 3
await requestFlag(scope, mode, async flag => {
await async_do_stuff();
}, {signal:controller.signal});
} catch (ex) {
if (ex.name === 'AbortError') { ... }
} |
I'm a little confused still. Either:
|
fwiw, you can abort a But anyway, I much prefer (3). |
Hrm, I think I was interpreting "allow signalling aborts" to mean: there's a promise you can watch that will reject with AbortError if the AbortSignal fires. Another interpretation is: there's a promise you can watch that rejects if the operation done while holding the flag rejects. In that case: yes, in (1) we could do that by having In the IDL sketch I also have |
Although these look somewhat equivalent, they're different if
async_write_func
rejects. ThewaitUntil
example will see the promise settle and release the lock, whereas the.release
example will never be released.To avoid forever-locking, you'd have to do:
Question is, is this enough of a footgun to justify
waitUntil
?The text was updated successfully, but these errors were encountered: