-
Notifications
You must be signed in to change notification settings - Fork 212
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
detecting an empty vat promise queue (end of "crank") #45
Comments
JavaScript specifies that the promise queue is higher priority than the timer queue. As a result, JS is guaranteed that it will not take outside events until the promise queue is empty. |
@dtribble, you note:
Since timers are not defined by JavaScript, I assume you are referring more generally to events delivered by the host using a mechanism other than promises (e.g. timer callbacks). Some non-definitive web searching appears to confirm that this may be the case in browsers. However, I was unable to find text in ECMA-262 that defines this behavior. That said ECMA-262 is huge, so I may well have overlooked that. This morning I only focused on Jobs and Job Queues section. If you wouldn't mind, would you help me with the normative reference for this behavior? Thank you! |
Attn @littledan What's the status of this? |
Link to PR please? |
Yes, that's what I was looking for. Thanks. |
@littledan writes Sep 19:
@phoddie that puts the ball in your court, yes? Would it help for me to open an issue in the Moddable repo? Has anyone added test262 tests for this? At what point in the process does that usually happen? In a few recent cases I was a little concerned that fixes went into the Moddable repo without corresponding tests, but then it occurred to me that the tests should probably go into test262. |
When the specification in ECMA-262 settles down, we can look at revised behavior. Making the above example work as expected is straightforward. However, I expect there are more subtle behaviors implied by the changes under discussion. Good coverage in test262 would help make the intentions clear. Finding an efficient implementation for what I understand the behavior to be looks to be non-trivial on microcontrollers where watch-dogs trigger if a single turn of the event loop runs for very long. |
What happens when these watch-dogs bark? Where can I read about this? I worry about the same consistency issue I explain at https://github.com/Agoric/proposal-oom-fails-fast |
Ha. Sorry for not explaining more. Let me try. The watchdogs detect software hangs - infinite loops, deadlocks, etc. When they trigger, the usual action is to reboot the microcontroller. These are used to ensure an embedded device doesn't become unresponsive as a result of a bug. The threshold can be quite low - 100ms. There is considerable variation in the details across microcontrollers, and often there are many configuration options. The ESP32 watchdog is reasonably representative. Unlike memory exhaustion, there's no consistency issue, as the watchdog reboots the entire device. My concern is implementing the behavior under consideration for run loops where a promise resolves a promise that resolves another promise in a long chain. Each step may be short enough to avoid the watchdog, but in total they are not. To avoid that, it appears necessary to exit the run loop before servicing the all promises and resume on the next turn without allow timers/etc to execute. That's possible. An easier work around is to "feed" the watchdog on each promise, effectively tell it "we didn't hang, we're just busy, so reset your timeout". But, there are problems with that. If the RTOS has work it only does when the event loop returns control to it, that would be deferred indefinitely. On an ESP8266, for example, the network stack runs at that time. Also, in my experience, feeding the watchdog has a bad habit of introducing subtle bugs that causing the watchdog to then fail to detect real issues. Anyway... I don't think there's an issue here from a JavaScript or SES perspective. I just believe there are implementation concerns that will take some care to arrive at a result that is both correct and efficient on the embedded device XS targets. |
Sorry, to clarify, the layering change does not say that Promises are higher priority than other jobs. That continues to be defined by the host environment. IMO it would be nice for the ecosystem to converge on this kind of scheduling where possible, but I understand if that's not appropriate for all environments. |
Thanks, @littledan. We're holding off on any implementation until the dust settles. To be clear, I'm not suggesting that we can't support the various event loop rules being discussed, only that there are some interesting challenges to implement them well in our target environments. |
R4R: Json and Stringer structs in querier instead of CLI
* update outdated packages * update ertp to 0.0.9
This rewrites most everything: the way objects+promises are referenced (both in vats and the kernel), the way messages manage their result promises, the kernel-side run-queue, the kernel-side promise tables, the way comms messages are formatted, the entire comms layer, and all the comms tests. The kernel now supports pipelining sends all the way into the deciding vat, and the comms vat will pipeling those sends to the remote deciding machine. It does not yet implement "forwarding" (replacing one promise with a different one), nor do promise references get deleted after their promise has been resolved. The comms vat must be created with the `enablePipelining` option set to `true` to get the pipelining behavior. closes Agoric#88 closes Agoric#34 closes Agoric#79 closes Agoric#45
preempting queued callbacks looks tricky with glibI found that the xs But
Recall the test code: const log = [];
setImmediate(() => log.push(1));
setImmediate(() => {
log.push(2);
Promise.resolve().then(() => log.push(4));
log.push(3);
});
setImmediate(() => log.push(5));
setImmediate(() => log.push(6));
t.deepEqual(log, [1, 2, 3, 4, 5, 6]); By the time the I was going to say this can't be done with glib, but they do break down
So we could make a customized version of |
Can we do something like: const waitForPromises = inXS
? cb => setTimeout(cb, 1) // or other XS primitive?
: cb => setImmediate(cb); because AFAICT, |
yes, @michaelfig , something like that. @warner and I chatted about this and now I think I understand the requirements better. It need not involve |
This seems complicated. Are you trying to implement the proposed behavior where settled promises always take priority over host callbacks?
I believe you are working on Linux? If so, it would seem easier to modify your Linux host in lin_xs.c. The promises callbacks are invoked when fxQueuePromiseJobsCallback calls fxRunPromiseJobs. fxRunPromiseJobs calls all promises settled when it begins execution, but not those settled during its execution.
Maybe something like this will do what you want?
gboolean fxQueuePromiseJobsCallback(void *it)
{
txMachine* the = it;
do {
fxRunPromiseJobs(the);
} while (mxPendingJobs.value.reference->next);
return G_SOURCE_REMOVE;
}
… On Dec 6, 2019, at 5:19 PM, Dan Connolly ***@***.***> wrote:
yes, @michaelfig <https://github.com/michaelfig> , something like that. @warner <https://github.com/warner> and I chatted about this and now I think I understand the requirements better. It need not involve setTimeout at all. I updated the issue title as such.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#45?email_source=notifications&email_token=ABUJ6CQT7WCLF3PUX6IFDO3QXL22NA5CNFSM4JTNXNW2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGF2DQY#issuecomment-562799043>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABUJ6CSKGYQK43XCK2XJF6LQXL22NANCNFSM4JTNXNWQ>.
|
Thanks, @phoddie . Something like that may very well work. But the core of the issue is not really priority of promises vs. host callbacks. It's about detecting when the promise queue of a "vat" under the control of a "kernel" is empty. The "kernel" was using |
But the core of the issue is not really priority of promises vs. host callbacks. It's about detecting when the promise queue of a "vat" under the control of a "kernel" is empty. The "kernel" was using setTimeout() to queue something that would only come back after the "vat" was done with all the promises it wanted to queue for itself.
How do you do that in a browser?
… On Dec 6, 2019, at 6:18 PM, Dan Connolly ***@***.***> wrote:
Thanks, @phoddie <https://github.com/phoddie> . Something like that may very well work.
But the core of the issue is not really priority of promises vs. host callbacks. It's about detecting when the promise queue of a "vat" under the control of a "kernel" is empty. The "kernel" was using setTimeout() to queue something that would only come back after the "vat" was done with all the promises it wanted to queue for itself.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#45?email_source=notifications&email_token=ABUJ6CVU4SEAFKTVSZQDXXDQXMBYBA5CNFSM4JTNXNW2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGF3OLY#issuecomment-562804527>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABUJ6CSYIM2L6PXDOKD7YR3QXMBYBANCNFSM4JTNXNWQ>.
|
Browsers presumably work like node. The original test passes in chrome (with |
I guess I'm not following the goals here well enough.
I more-or-less understand how JavaScript behaves and how the XS host provides parts of that. I don't know about vats and kernels and the needs they have from promises.
I apologize for jumping in. I'll stand aside on this one.
… On Dec 6, 2019, at 9:20 PM, Dan Connolly ***@***.***> wrote:
Browsers presumably work like node. The original test passes in chrome (with const setImmediate = f => setTimeout(f, 0)).
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#45?email_source=notifications&email_token=ABUJ6CUTWJHS7WFRTY3A5PTQXMXCJA5CNFSM4JTNXNW2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGF6GXA#issuecomment-562815836>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABUJ6CS4NTQ35QC2WO65HX3QXMXCJANCNFSM4JTNXNWQ>.
|
Yeah; I put "vat" and "kernel" in quotes because they're somewhat local terms of art. There are some docs in https://github.com/Agoric/agoric-sdk/tree/master/packages/SwingSet/docs but I'm not sure even those are up to date. No need to apologize; I think you may well have helped. But standing aside is fine too. |
On xs, I'm getting:
I traced it to empty agoric-sdk/packages/SwingSet/src/kernel/vatManager.js Lines 214 to 216 in f833610
Is it possible this queue priority stuff is to blame? |
fixed in #2194 |
double-check that the |
Oh yeah... we turned off |
In #2225 (comment) @kriskowal writes:
|
This test seems to be failing on xs (now that my tape work-alike is actually working):
https://github.com/Agoric/SwingSet/blob/7cd651107a31ba84d9b9f11610d72b5477035fd9/test/test-queue-priority.js#L5
What's the justification for that test? Is the queue priority specified?
In what way does SwingSet rely on the queue priority?
cc @warner @phoddie
The text was updated successfully, but these errors were encountered: