-
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
refactor(swingset): improve vat deliveries #4716
Conversation
recommend reviewing with "hide whitespace", to reduce the diff |
13aaf15
to
b7fd9a6
Compare
'xs-worker-no-gc', | ||
].includes(mt), | ||
); | ||
return undefined; |
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.
Won't a function return undefined
anyway if you don't have an explicit return
statement? Or is this to deal with some kind of TypeScript nonsense?
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.
yeah, typescript
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.
That would be the difference between a return type of void
vs undefined
.
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 know if there's a better way to write that assertion function, I just copied something else that works
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.
Assertions don't require a return value in TS. This might be a case of jsdoc eslint plugin not understanding assertions ?
b7fd9a6
to
f0f5f0d
Compare
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 is a very nice blood pressure reducing cleanup! I particularly like getting rid of the output named policyInput
which, even though I kinda sorta understood the reasoning behind the name, has always bugged me.
f0f5f0d
to
126acf2
Compare
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 looks great! Thanks so much for starting this refactor.
I'm not familiar enough with the termination conditions and the start vat logic to be confident enough in my review for those parts, and I trust @FUDCo on his approval there.
The requested change is for the extension in the import
in the types file, in case that file ever ends up actually imported by ES code someday. Rest is mostly nits on types and consistency.
'xs-worker-no-gc', | ||
].includes(mt), | ||
); | ||
return undefined; |
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.
Assertions don't require a return value in TS. This might be a case of jsdoc eslint plugin not understanding assertions ?
/** | ||
* | ||
* @returns { ManagerType } | ||
*/ |
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.
FYI this should be unnecessary given that mt
should be typed correctly after the assertion.
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 can remove the @returns { ManagerType }
, thanks. (I started from kernel.js
that calls this, added the @returns
so the options.managerType = kernelKeeper.getDefaultManagerType()
didn't complain, and then added the assertion to make the @returns { ManagerType }
shut up.. should have started with the assertion).
If I remove the return undefined;
from insistManagerType()
, I get this warning:
$ eslint '**/*.js'
/home/warner/stuff/agoric/agoric-sdk/packages/SwingSet/src/kernel/state/kernelKeeper.js
310:3 warning JSDoc @returns declaration present but return expression not available in function jsdoc/require-returns-check
I don't know how to make that go away, so I'm inclined to leave the return undefined;
, but if you know a way, I'll apply it.
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.
Yeah sounds like a limitation of the JSDoc eslint plugin, not a problem with typescript. Besides an ugly eslint disable.
An alternative might be to return mt
instead.
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.
return mt;
gets me Type 'string' is not assignable to type 'void
. I don't know how to express "returns $type and also asserts that the input value is $type".
* @typedef { { meterID?: MeterID } } HasMeterID | ||
* @typedef { import('./types-exported.js').DynamicVatOptionsWithoutMeter } DynamicVatOptionsWithoutMeter | ||
* | ||
* vatKeeper.setSourceAndOptions(source, RecordedVatOptions) |
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 line seem out of place.
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.
it was a reminder of where RecordedVatOptions
gets used.. is there a better way to do comments within JSDoc comments? I could use * // vatKeeper.set...
maybe.
56fb177
to
a946352
Compare
// `vatFatalSyscall`. We'd still need a way for `requestTermination` to | ||
// work, though. |
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.
Note to self: could this be handled a similar way, something in the vat translation layer that remembers the exit
call?
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, you know, we should consider making the syscall.exit
handler just push an terminate-vat
event onto the vat's own input-queue, and perform the teardown later. Sort of "please shut me down, eventually, when it's convenient". Then vat-manager or the translation layer doesn't need to remember anything. And if our scheduler's policy always drains the vat-output-queue before looking at the vat-input-queue, then this would automatically deliver all the previously-emitted work before shutdown, which might line up nicely with our plans around involuntary termination needing to not interfere with previous output, and might simplify the "vat is dead but queues are not" question.
I don't know enough about our use cases for this to know whether promptness is important to us. Maybe it'd be when a contract has finished transferring all its assets and obligations to a successor, and it self-destructs to free up chain capacity, and to prevent surprises when people try to talk to the old one by mistake? Seems like the vat would know that it's in this state, so it could maybe reject all attempts to start new work while waiting to be terminated. OTOH, it would be really annoying to have to add extra "am I active" checks in vat code to make up for the platform not being able to respond to a syscall.exit
promptly. We might work around this by configuring the input scheduler to service terminate-vat
events ahead of anything else (but still behind draining the output queue).
@@ -0,0 +1,17 @@ | |||
import './types.js'; | |||
import './types-exported.js'; |
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'm surprised we still need the exported
one.
* // used by vatKeeper.setSourceAndOptions(source, RecordedVatOptions) | ||
* | ||
* @typedef { DynamicVatOptionsWithoutMeter & HasMeterID } InternalDynamicVatOptions | ||
* @typedef { StaticVatOptions | { InternalDynamicVatOptions & HasMeterID } } RecordedVatOptions |
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'm confused why this doesn't require a import('./types-exported.js').StaticVatOptions
This moves some logic out of `deliverAndLogToVal` and into a higher-level dispatch function, where it can react to all failure modes in a single place. We pull "run-queue events" off the run-queue (currently named the "acceptance queue". Many of these events are aimed at a specific vat, including 'notify', but the primary one is 'send' and is aimed at a *target* kref, which is either a kernel object or a kernel promise. For these we use `routeSendEvent` to either queue the event on a promise queue, reject it if it can't be delivered, or deliver it to a specific vat. This is the part that will change with #3465: in that world, each vat-input-queue exists for a specific vat, so the routing step moves earlier (into a "routing crank" that pulls events from a vat-output-queue and possibly adds them to a vat-input-queue). Some kinds of deliveries care about metering (or don't), and some have opinions about what should happen if a crank gets unwound. These are now reported as additional properties in the DeliveryStatus object that is returned by this delivery path. `processDeliveryMessage` looks at these properties, plus the delivery status (if any) to decide what to do at the end of the crank. I think most of the behavior should be the same as before. One change is that the `runPolicy` will probably get more information about non-'send' cranks than before (e.g. `create-vat` might report metering). This refactoring should make it easier to implement #1848 vat-upgrade, as well as #3465 queueing changes. closes #4687
Add "re-exporting" ambient file for backwards compatibility
996ad6b
to
f62335a
Compare
This moves some logic out of
deliverAndLogToVal
and into a higher-leveldispatch function, where it can react to all failure modes in a single place.
We pull "run-queue events" off the run-queue (currently named the "acceptance
queue"). Many of these events are aimed at a specific vat, including 'notify',
but the primary one is 'send' and is aimed at a target, which is either a
kernel object or a kernel promise. For these we use
routeSendEvent
toeither queue the event on a promise queue, reject it if it can't be
delivered, or deliver it to a specific vat. This is the part that will change
with #3465: in that world, each vat-input-queue exists for a specific vat, so
the routing step moves earlier (into a "routing crank" that pulls events from
a vat-output-queue and possibly adds them to a vat-input-queue).
Some kinds of deliveries care about metering (or don't), and some have
opinions about what should happen if a crank gets unwound. These are now
reported as additional properties in the DeliveryStatus object that is
returned by this delivery path.
processDeliveryMessage
looks at theseproperties, plus the delivery status (if any) to decide what to do at the end
of the crank.
I think most of the behavior should be the same as before. One change is that
the
runPolicy
will probably get more information about non-'send' cranksthan before (e.g.
create-vat
might report metering).This refactoring should make it easier to implement #1848 vat-upgrade, as
well as #3465 queueing changes.