-
Notifications
You must be signed in to change notification settings - Fork 215
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
fix(swingset): abandon/delete most non-durables during stopVat() #5056
Conversation
fe4e829
to
4a2bedb
Compare
4a2bedb
to
bebbb97
Compare
Note that this introduces O(numcollections) RAM usage until we replace it with something for #5058. |
bebbb97
to
c549478
Compare
Oh, one significant question: how should we access things like |
I'm not entirely sure what you mean by "within the swingset source tree". Tests that use |
I mean tests under Looking more closely, it appears that I'll make these unit tests use |
Seems like all dependencies that tests have should be dev dependencies, or at least all dependencies that aren't already runtime dependencies of the package under test itself. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor nits but nothing substantive. I remain concerned about the memory footprint of all the various intermediate data structures being used to track the stuff being deleted as we're deleting it, but I think that's out of scope for this PR.
@@ -549,9 +555,13 @@ export function makeCollectionManager( | |||
} | |||
|
|||
function deleteCollection(vobjID) { | |||
if (!allCollectionObjIDs.has(vobjID)) { | |||
return false; // already deleted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what situation could cause us to get to here, but if we do I'm betting it's probably a bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be triggered by the violence I'm doing to the refcounts: the "delete all collections" pass deletes collection-1, then a subsequent BOYD drops the last (real) reference to it, so the refmgr tries to delete it again, causing a crash when it can't find the export status.
This will be a lot better with the scheme we cooked up (#5090).
// vats to cause confusion in the new version (by referencing exports | ||
// which the vat no longer remembers). | ||
|
||
const rootSlot = makeVatSlot('object', true, BigInt(0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BigInt(0)
--> 0n
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aye, I was having problems with 0n
killing my editor's syntax parser, but that's because it's an old version of the plugin
// and attached a .then to it), and stopVat() must not allow | ||
// userspace to gain agency. | ||
|
||
const rejectCapData = m.serialize('vat upgraded'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a bit of OCD in me that is bothered by the 'vat upgraded'
text because the vat might not yet have been upgraded when whoever's waiting on the promise receives the rejection. Kind of like those early Final Fantasy games where you saw text narrating combat in the past tense just before you were shown the animation of the combat. Maybe 'vat halted for upgrade
' or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, think of it this way: the only way for anybody to see this message is if the vat was successfully upgraded, because if something failed, all state would get rolled back, including the rejection of those promises. The anthropological argument always wins, as far as you know :).
35f61cd
to
3095a03
Compare
3095a03
to
dbec304
Compare
This deletes most non-durable data during upgrade. stopVat() delegates to a new function `releaseOldState()`, which makes an incomplete effort to drop everything. The portions which are complete are: * find all locally-decided promises and rejects them * find all exported Remotables and virtual objects, and abandons them * simulate finalizers for all in-RAM Presences and Representatives * use collectionManager to delete all virtual collections * perform a bringOutYourDead to clean up resulting dead references After that, `deleteVirtualObjectsWithoutDecref` walks the vatstore and deletes the data from all virtual objects, without attempting to decref the things they pointed to. This fails to release durables and imports which were referenced by those virtual objects (e.g. cycles that escaped the earlier purge). Code is written, but not yet complete, to decref those objects properly. A later update to this file will activate that (and update the tests to confirm it works). The new unit test constructs a large object graph and examines it afterwards to make sure everything was deleted appropriately. The test knows about the limitations of `deleteVirtualObjectsWithoutDecref`, as well as bug #5053 which causes some other objects to be retained incorrectly. The collectionManager was changed to keep an in-RAM set of the vrefs for all collections, both virtual and durable. We need the virtuals to implement `deleteAllVirtualCollections` because there's no efficient way to enumerate them from the vatstore entries, and the code is a lot simpler if I just track all of them. We also need the Set to tolerate duplicate deletion attempts: `deleteAllVirtualCollections` runs first, but just afterwards a `bringOutYourDead` might notice a zero refcount on a virtual collection and attempt to delete it a second time. We cannot keep this Set in RAM: if we have a very large number of collections, it violates our RAM budget, so we need to change our DB structure to accomodate this need (#5058). refs #1848
dbec304
to
1cfbeaa
Compare
This deletes most non-durable data during upgrade. stopVat() delegates
to a new function
releaseOldState()
, which makes an incompleteeffort to drop everything.
The portions which are complete are:
After that,
deleteVirtualObjectsWithoutDecref
walks the vatstore anddeletes the data from all virtual objects, without attempting to
decref the things they pointed to. This fails to release durables and
imports which were referenced by those virtual objects (e.g. cycles
that escaped the earlier purge).
Code is written, but not yet complete, to decref those objects
properly. A later update to this file will activate that (and update
the tests to confirm it works).
The new unit test constructs a large object graph and examines it
afterwards to make sure everything was deleted appropriately. The test
knows about the limitations of
deleteVirtualObjectsWithoutDecref
, aswell as bug #5053 which causes some other objects to be retained
incorrectly.
The collectionManager was changed to keep an in-RAM set of the vrefs
for all collections, both virtual and durable. We need the virtuals to
implement
deleteAllVirtualCollections
because there's no efficientway to enumerate them from the vatstore entries, and the code is a lot
simpler if I just track all of them. We also need the Set to tolerate
duplicate deletion attempts:
deleteAllVirtualCollections
runs first,but just afterwards a
bringOutYourDead
might notice a zero refcounton a virtual collection and attempt to delete it a second time. We
cannot keep this Set in RAM: if we have a very large number of
collections, it violates our RAM budget, so we need to change our DB
structure to accomodate this need (#5058).
refs #1848