-
Notifications
You must be signed in to change notification settings - Fork 214
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
have kernel reject unresolved vat-decided promises of an upgraded vat #6694
Comments
When upgrading a vat, we must reject all promises that were decided by the old incarnation, because none of them are durable (the new incarnation will be unable to resolve them). Previously, the vat's stopVat() delivery would do the rejection. This moves the responsibility to the kernel, to happen in the pause between the old version being shut down and the new version being launched. closes #6694
I have an incomplete branch for the work in https://github.com/Agoric/agoric-sdk/tree/6694-kernel-disconnect-promises . I think it's mostly done, but I haven't run the tests yet. We should look at |
The changes of https://github.com/Agoric/agoric-sdk/tree/6694-kernel-disconnect-promises are causing difficult-to-diagnose vat upgrade test failures. I'm adding a new test to packages/SwingSet/test/upgrade/test-upgrade.js that uses bootstrap-relay.js with a new option to skip promise/remotable replacement and is much simpler than |
When upgrading a vat, we must reject all promises that were decided by the old incarnation, because none of them are durable (the new incarnation will be unable to resolve them). Previously, the vat's stopVat() delivery would do the rejection. This moves the responsibility to the kernel, to happen in the pause between the old version being shut down and the new version being launched. closes #6694
Down to 19 failing tests, and looking like mostly reordering of promise settlement. I'm going to try moving the the kernel takeover to after |
When upgrading a vat, we must reject all promises that were decided by the old incarnation, because none of them are durable (the new incarnation will be unable to resolve them). Previously, the vat's stopVat() delivery would do the rejection. This moves the responsibility to the kernel, to happen in the pause between the old version being shut down and the new version being launched. closes #6694
The last remaining gap affects local promises observed by durable promise watchers, which must now be exported to the kernel so it can reject them as part of upgrade. |
When upgrading a vat, we must reject all promises that were decided by the old incarnation, because none of them are durable (the new incarnation will be unable to resolve them). Previously, the vat's stopVat() delivery would do the rejection. This moves the responsibility to the kernel, to happen in the pause between the old version being shut down and the new version being launched. closes #6694
What is the Problem Being Solved?
As listed in #6650, when a vat is upgraded, it's
stopVat
is currently responsible for rejecting ("disconnecting") all of that vat's Promises (i.e. all the Promises for which the upgraded vat was the decider). We do this because we don't have durable pseudo-promises (#3787), so the V2 version of that vat cannot possibly have access to theresolve()
/reject()
facets on those promises, so there's no way for them to become resolved ever again. We reject these promises during upgrade, with a distinctive value (so clients can distinguish "owner upgraded" vs "owner deliberately rejected"), which allows clients of e.g. durable Notifiers in the upgraded vat to come back and ask for a new Promise from the new version.As part of #6650, we're moving responsibility for this task from the old vat into the kernel. The kernel will reject these promises just after it shuts down the old worker, and just before it starts the new one.
Description of the Design
The kernel will walk the vat's c-list to find all promises known to the vat. These should all be unresolved, because we retire vpid/vrefs and c-list entries immediately upon resolution. For each kpid in the c-list, the kernel it will examine the kernel promise table to find the subset that are decided by the vat being upgraded. (In the future, perhaps as part of #6677 , we might use a better index to find this set of kpids more efficiently). The code to do this is already part of
kernelKeeper.cleanupAfterTerminatedVat
, as called by kernel.jsterminateVat
.The kernel will reject these promises, using the same
disconnectObject
that we currently pass as an argument intostopVat
(the one that containsupgradeMessage
and the oldincarnationNumber
).Inside the vat, we'll modify the Durable Promise Watcher:
syscall.subscribe()
to the vpid, even if the promise is being exported at that timesyscall.subscribe()
, if we don't already have one. This might already work fine, but it's a new case that we need to checkdispatch.notify()
events for self-decided/exported promises from the old version. Previously these were tracked internally in thedeadPromises
vatstore keyprepareShutdownRejections
fromliveslots/watchedPromises.js
, alone with thedeadPromises
table, anddeadPromisesDO
for the disconnect objectloadWatchedPromiseTable
, remove the reads ofdeadPromises
/deadPromiseDO
, and the code that handles promises which were in this table. Instead, all promises in thewatchedPromiseTable
will be revived, and then the kernel will deliverdispatch.notify()
for the ones that were disconnectedkernelQueue.js
'sdoResolve()
function to enqueue anotify()
to all subscribers, not skipping the deciding vat: vats are allowed to subscribe to their own promises, and they'll be notified if/when those promises are resolveddispatch.notify()
of a promise that's missing from the slotToVal table (which we added because a notify might be queued at the time of a vat upgrade, and the new version would not remember subscribing)Compatibility Considerations
In this new approach, self-exported promises will deliver their rejections (within the new vat version) slightly later than before. Previously,
startVat
sent these rejections, so they'll all be executed during thestartVat
delivery (after module load, afterbuildRootObject
is called again, but still in the same crank, and before any new messages can be delivered). After this change, the rejections will be pushed onto the run-queue during upgrade, so they won't be delivered until after everything else currently on the run-queue is delivered.Test Plan
Unit tests
The text was updated successfully, but these errors were encountered: