Skip to content

Commit

Permalink
feat: vat warehouse for LRU demand paged vats (#2784)
Browse files Browse the repository at this point in the history
initial policy: most recently used 20 vats are kept online

Note that it's important to handle rejection in wasTerminated: in
addition to the error path for the failed execution, there's an error
generated when shutting down the xsnap subprocess.

 - buildKernel:
   - makeVatWarehouse takes over
     - instantiating static, dynamic vats in start()
     - ephemeral.vats
       - vatWarehouse.lookup() replaces ephemeral.vats.has()
     - addVatManager, removeVatManager
     - deliverToVat
   - re-wire notifyTermination
 - makeVatLoader:
   - create methods return Promise<VatManager>
   - translators are passed in
   - no longer uses vatNameToID, queueToExport
   - notifyTermination has been hoisted to its own file
   - clarify source bundle type
 - test vat-target: exhibit stateful behavior

* refactor(swingset): refine types for ManagerOptions, CapData

 - ManagerOptions includes enablePipelining, notifyTermination
 - align type annotations with where CapData slots are parsed
 - replayTranscript is async

* docs(swingset): panic() does *not* throw

After thorough investigation, let's be explicit that panic() does
not (unconditionally) throw but rather normally returns.

Add explicit default value for err arg too.

Also, clean up a couple awaits on resolveToError(), which does not
return a Promise.

* docs(xs-worker): handleCommand on manager side is async

* style: js idioms, replay in parallel note

 - replace boolean shortcuts with helper function
 - convert lookup from arrow function
 - note optimization opportunity: replay vats in parallel

* chore(vat-warehouse): raise default size of LRU cache to 50

* test(vat-warehouse): 4 vats in warehouse with room for 2 online

* feat: get maxVatsOnline from swingset config

* chore(loadVat): kernelSlog can't repeat addVat()

* chore(vat-warehouse): postpone enablePipelining optimization etc.

 - note makeVatTranslators precondition
 - punt on provideVatKeeper refactor
 - punt on note about comms vat source repeated

We had a TODO to "add a way to remove a vatKeeper from ephemeral in
kernel.js so that we can get rid of a vatKeeper when we evict its
vat"; I tried a `pruneVatKeeper()` method on `kernelKeeper` but it
failed with `resolution of "kp40" is still pending`.

* chore: fix notifyTermination merge

* chore(vat-warehouse): close transcript on evict

* docs(swingset): clean up terminateVat docstring

* feat(swingset): controller.getStatus() for online vats etc.

 - provide type for kernel
 - factor out defensiveCopy

* chore(vat-warehouse): evict old vats when bringing new ones online

* test(vat-warehouse): check online vats after each delivery

* docs: fix stray initSwingStore reference in @typedef

* chore(swingset): handle vat page-in in kernelSlog

* refactor: findOrCreateTranslators -> provideTranslators

* chore: don't try to closeTranscript() on a terminated vat

* chore: async call needs await

Thanks for review, BW.
  • Loading branch information
dckc authored Jun 9, 2021
1 parent a2e2d3a commit 05f3038
Show file tree
Hide file tree
Showing 17 changed files with 570 additions and 183 deletions.
2 changes: 1 addition & 1 deletion packages/SwingSet/src/capdata.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { assert, details as X } from '@agoric/assert';
* @param {any} capdata The object to be tested
* @throws {Error} if, upon inspection, the parameter does not satisfy the above
* criteria.
* @returns {asserts capdata is CapData}
* @returns {asserts capdata is CapData<unknown>}
*/
export function insistCapData(capdata) {
assert.typeof(
Expand Down
23 changes: 20 additions & 3 deletions packages/SwingSet/src/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export function makeStartXSnap(bundles, { snapstorePath, env, spawn }) {
* slogCallbacks?: unknown,
* slogFile?: string,
* testTrackDecref?: unknown,
* warehousePolicy?: { maxVatsOnline?: number },
* snapstorePath?: string,
* spawn?: typeof import('child_process').spawn,
* env?: Record<string, string | undefined>
Expand All @@ -148,6 +149,7 @@ export async function makeSwingsetController(
slogFile,
snapstorePath,
spawn = ambientSpawn,
warehousePolicy = {},
} = runtimeOptions;
if (typeof Compartment === 'undefined') {
throw Error('SES must be installed before calling makeSwingsetController');
Expand Down Expand Up @@ -303,7 +305,8 @@ export async function makeSwingsetController(
gcAndFinalize: makeGcAndFinalize(engineGC),
};

const kernelOptions = { verbose };
const kernelOptions = { verbose, warehousePolicy };
/** @type { ReturnType<typeof import('./kernel').default> } */
const kernel = buildKernel(kernelEndowments, deviceEndowments, kernelOptions);

if (runtimeOptions.verbose) {
Expand All @@ -312,6 +315,13 @@ export async function makeSwingsetController(

await kernel.start();

/**
* @param {T} x
* @returns {T}
* @template T
*/
const defensiveCopy = x => JSON.parse(JSON.stringify(x));

// the kernel won't leak our objects into the Vats, we must do
// the same in this wrapper
const controller = harden({
Expand All @@ -322,7 +332,7 @@ export async function makeSwingsetController(
writeSlogObject,

dump() {
return JSON.parse(JSON.stringify(kernel.dump()));
return defensiveCopy(kernel.dump());
},

verboseDebugMode(flag) {
Expand All @@ -342,7 +352,11 @@ export async function makeSwingsetController(
},

getStats() {
return JSON.parse(JSON.stringify(kernel.getStats()));
return defensiveCopy(kernel.getStats());
},

getStatus() {
return defensiveCopy(kernel.getStatus());
},

// these are for tests
Expand Down Expand Up @@ -393,6 +407,7 @@ export async function makeSwingsetController(
* slogCallbacks?: unknown,
* testTrackDecref?: unknown,
* snapstorePath?: string,
* warehousePolicy?: { maxVatsOnline?: number },
* }} runtimeOptions
* @typedef { import('@agoric/swing-store-simple').KVStore } KVStore
*/
Expand All @@ -408,12 +423,14 @@ export async function buildVatController(
debugPrefix,
slogCallbacks,
snapstorePath,
warehousePolicy,
} = runtimeOptions;
const actualRuntimeOptions = {
verbose,
debugPrefix,
slogCallbacks,
snapstorePath,
warehousePolicy,
};
const initializationOptions = { verbose, kernelBundles };
let bootstrapResult;
Expand Down
Loading

0 comments on commit 05f3038

Please sign in to comment.