-
Notifications
You must be signed in to change notification settings - Fork 226
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
Virtual object garbage collection #3513
Conversation
Nice work! The changes are a lot smaller than I expected.. that's awesome. I've walked through everything and I agree that this is sound (it's not going to drop anything that it shouldn't drop), and the status quo of the I think there's a redundancy that should be cleaned up, because it's going to confuse us during the next phase. This PR uses both
As a separate requirement,
In this PR, you're changing function possibleVirtualObjectDeath(vobjID) {
if (!isVrefReachable(vobjID) && !getValForSlot(vobjID)) {
const [exported, refCount] = getRefCounts(vobjID);
if (exported === 0 && refCount === 0) {
syscall.vatstoreDelete(`vom.${vobjID}`);
syscall.vatstoreDelete(`vom.${vobjID}.refCount`);
}
So here's my suggestion:
const [exported, refCount] = getRefCounts(vobjID);
if (!getValForSlot(vobjID) && exported === 0 && refCount === 0) {
// delete.. I'll add some other suggestions inline. |
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.
Code looks good but let's make those cleanups for the sake of our sanity in the next phase. I'm confused by the tests (probably by the VOM's caching) but I'll keep studying them.
} | ||
nextThingNumber += 1; | ||
} | ||
console.log(`Bob finishing`); |
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.
I find this test pretty confusing. If I read it correctly, by the time finish()
finishes, the virtual objects originally associated with the Representatives in things[]
are left in the following states
number | exported | has Representative | in virtualized data | notes |
---|---|---|---|---|
1 | exported+dropped | no | no | Rep dropped before kernel drops |
2 | exported+dropped | yes | no | |
3 | never | no | no | |
4 | exported+retained | no | no | |
5 | never | no | no | |
6 | never | no | no | |
7 | never | yes | no | no |
8 | never | yes | no | no |
9 | never | yes | no | no |
The test is asserting:
v1.vs.vom.o+1/2
(that's thing2, right?) has a 0/0 refcount: good, it's kept alive by the Representative pillar and nothing else../3
(thing3) has a 1/0 refcount .. wait, thing4 should have 1/0 (kept alive by the kernel-export pillar, but no Representative), am I off-by-one already? ThevobjID
are assigned upon object creation, not export, yeah?../4
through../7
are deleted: I'm off again, it looks like thing7 should be retained by a Representative../8
and../9
have data but no refcounts, which seems slightly weird, but I guess you're avoiding the DB expense for virtual objects that are retained by only a Representative and not by either a kernel-export or virtualized-data?
If we can enumerate the cases we care about, it might be easier to follow this test (and to enhance it in the future) to make them all explicit. Create a batch of Representatives, forget a few, export a few, store a few in virtualized data. Wait for the peer to drop some of the exported ones. Forget a few more (to test both orderings: Representative collected before kernel drops, kernel drops before Representative collected). Then let the test runner look at the DB and make sure everything matches the expectations.
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.
These cases will remain confusing until we have implemented all three legs of the tripod. Remember that at this point we've only got 2, because using something in a property value pins it forever.
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.
Let me see if I can make this clearer (I'll turn this into a comment in the test if so):
First of all, nothing in this test exercises a case where any virtual object refers to any other virtual object, so the fourth column of your table is nugatory. Also, I'm not sure what the batch of "no"s in the lower portion of the table in the Notes column even means. With respect to any given case, we really only have two variables to fiddle with: whether a reference to the VO is exported, and whether a reference to the VO is retained in memory in the vat.
For the first variable, there are three possible states: not exported, exported and then retained externally, exported and then dropped externally.
For the second variable, there are two possible states: retained internally, and dropped internally.
That would seem like 6 cases, but that's not quite true, since a reference that is dropped internally before being exported can't ever be exported. (Also if a VO has both an exported reference and an internal reference and both are dropped, we still have to worry about what order they're dropped in, but it's the other test that worries about the order of droppage issue).
number | exported? | export dropped? | local dropped? | deleted? |
---|---|---|---|---|
1 | yes | yes | yes | yes (dropped both locally and by export) |
2 | yes | yes | no | no (retained in things ) |
3 | yes | no | yes | no (retained by export) |
4 | no | n/a | yes | yes (dropped before use) |
5,6,7 | no | n/a | yes | yes (dropped at end) |
8,9 | no | n/a | no | no (retained unused) |
Things 5, 6, and 7 are essentially the same as 4, but they were handled in a loop at the end, to make sure that that worked.
Things 8 and 9 are both the same. They were never used and so were retained where they were originally stashed on creation.
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.
Ooookay, I think I see how that table might come out of the logic in getThing
, but I don't think I'd be able to figure that out by reading the test (and obviously I've already gotten it wrong once). Thank's for adding the table to the test case, that will help me a lot.
We should check with @katelynsills to see if ERTP wants to put Payments in a WeakSet or as the key of a WeakMap (I seem to remember a de-duplicating WeakSet in |
The paymentLedger is a |
And that Let's see, our current
Got it. And is that anti-aliasing taking place in the Zoe vat, which might not be the one where the Payment was created? So it might be dealing with Presences. But in either case, using a native Set is great, that doesn't interact with our virtual object manager at all, and it will properly drop everything when the Set itself is deleted. |
Yes! This is part of the ERTP code which is invoked when
Yup, the Brand will also be in the same vat. It's trivial to change the paymentLedger to use a Value instead of an Amount, if that would be helpful. We have an issue for it, but it hasn't been prioritized.
Nope, this is still part of core ERTP (only occurs in |
@@ -849,6 +835,10 @@ function build( | |||
if (o) { | |||
exportedRemotables.delete(o); | |||
} | |||
const { virtual } = parseVatSlot(vref); |
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 for today, but a future refactoring to make: since this is now the third time vref
is getting parsed, we should probably rearrange this to have a top-level loop on vrefs
, parse it once inside the loop, then have all three checks (type, allocatedByVat, virtual/not-virtual) after that parse
Ok, let's land this, but let's make sure to fix that |
This implements the first stage of VOM GC: garbage collection of virtual objects per se.
This does not yet deal with virtual objects (or any other kind of objects) that are referenced from virtual object properties -- these are still pinned using the mechanisms that we had in place for that purpose prior to this. Nor does it implement GC of virtual object keyed entries in weak collections. These will come in a later PR.
Commits are organized topically for ease of review.
Closes #3456