-
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
Store stateShape
in VOM metadata
#7338
Comments
Lemme review the basics, to understand what's really required here. Virtual/Durable -object Kinds have
Virtual Kinds don't outlive the incarnation, nor do their instances, so their Durable Kinds are redefined at the start of each incarnation (and if I just finished a PR (#7334) to make sure It would make sense to enforce a similar requirement for
Now, if we want the new incarnation's
such that instances created under v1 are still readable in v2. Some migration process rewrites all those instances during v2, so that by the time we upgrade to v3, all the records are compatible with the new constraint. Our refcounts would hold onto both instances during v2, then drops But if we want compression too, then we need to know which shape was used for each individual instance. We could keep them all, in the DurableKindDescriptor record, indexed by Or (as @erights suggested) we calculate a slower-moving counter that only increments when we observe the the shape changing (which might reduce the rate data-upgrade calls we must make). Or, Since we're thinking about data-migration processes here, we might also want some per-incarnation counters on the Kind, to remember how many objects we have of each incarnation, to schedule background migration work. Or an accomplishment tracker that remembers "all objects with ID below this value have been upgraded". |
Some more thoughts:
const initData = obj => ({ obj });
const behavior = {};
function createPredicate(objectX) {
const stateShape = M.or(objectX, 0);
const makeFoo = defineDurableKind(handle, initData, behavior);
const isX = harden(specimen => {
try {
makeFoo(specimen); // drop any successful result
return true;
} catch (e) {
return false; // assume matches() failed
});
return isX;
} We immediately drop any successfully-created instances, so the object is never serialized long enough to reach the database (modulo BOYD timing), so that data never holds a strong reference to the object. Technically, we could implement this to have the Note that there is no way to retrieve the
const initData = obj => ({ obj });
const behavior = {
get: ({ state }) => state.obj,
};
function hold(objectX) {
const stateShape = objectX;
const makeFoo = defineDurableKind(handle, initData, behavior);
const foo = makeFoo(objectX);
const get = harden(() => foo.get();
return get;
} The serialized instance data, in the DB, does not hold the object: it gets compressed out. Only the stored Again, technically, we could implement this in a way that had Since Kinds are low-cardinality, it's also not worth the effort to allow any Presences or Representatives in The PlanFor durable Kinds, we'll serialize By serializing it, we'll be able to write a comparison/compatibility-checking function to apply in the future. By incrementing refcounts, we'll be able to give that function unserialized Patterns instead of asking it to work on serialized data. If the shape is unconditional (no TODO: we might consider not incrementing refcounts on the For now, we'll store this serialized Next, when we introduce compression, we can leave the structures alone, and just change the serialization/deserialization code to refer to the stored shape when decompressing. Around that time, we can introduce versioned records. The KindDescriptor can continue to use The VOM data records must change: our current record-of-capdatas structure has completely consumed the space of possible records (we don't forbid any property names, even an empty string, so there's no room left for metadata). So we'll change them to an array, of In this period, upgrades must not change the shape, or at least they must not change the order of the stored fields. But knowing the shape of each version, we might be able to accomodate shape changes somehow. The KindDescriptor also holds the next instance ID, so it's a bit too "hot" to hold large cold data like state shapes. So we might want to split it into separate vatstore keys, a hot counter and a cold metadata one. Given the disruption of that, we might want to do that now, rather than later, even if we don't need the extra metadata for a while yet. |
To be clear, I'm also ok with lazy migration, or best-effort migration that may not complete ugprading v1 to v2 by the time we switch to v3. It sounds like @erights and @mhofman are thinking that userspace will be obligated to handle state data from any previous version, i.e. super-lazy migration. We'll need to provide userspace with some hint to let it know which era the data was from. This might be a numeric version ID, or some other string. I had been thinking of an integer that is incremented each time we redefine the Kind (once per incarnation, so basically the incarnation number), or maybe once each time the
We could include a constraint that if When calling My one naming quibble is that the interpretation of the state data might change even though the shape does not (imagine changing a timestamp from milliseconds to seconds, without also changing the property name). So As written, there's no support for letting userspace authors know when it's safe to stop supporting a given old version. It might be nice to give them a histogram of how many instances are using which versions of the data. This could either be done in-line (maintain some durable counters, add an API to retrieve them), or offline (publish a tool that crawls the DB and produces a report). The offline form would have less impact on the code, of course, and it's not clear that the data is needed by vat code, when it's the author of that vat code who needs to act upon it. |
What is the Problem Being Solved?
To enforce compatibility of
stateShape
checks when upgrading (#7337), we need to persist thestateShape
across upgrades. Currently the pattern is closed over by the kind definition, and thus lost.Description of the Design
Add
stateShape
to the durable metadata already saved about Virtual Objects (keyShape
,valueShape
).The text was updated successfully, but these errors were encountered: