Skip to content

Commit

Permalink
feat(swingset): config for xs-worker vs. local default
Browse files Browse the repository at this point in the history
config.defaultManagerType:
 - initializeSwingset() validates; passes to initializeKernel()
   and then to createStartingKernelState(), which stores it
 - setSourceAndOptions(), createVatDynamically() consult
   kernelKeeper.getDefaultManagerType()
  • Loading branch information
dckc committed Mar 30, 2021
1 parent 78b428d commit 973b403
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 19 deletions.
5 changes: 1 addition & 4 deletions packages/SwingSet/src/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ export async function makeSwingsetController(
slogCallbacks,
slogFile,
testTrackDecref,
defaultManagerType = env.WORKER_TYPE || 'local',
} = runtimeOptions;
if (typeof Compartment === 'undefined') {
throw Error('SES must be installed before calling makeSwingsetController');
Expand Down Expand Up @@ -230,7 +229,7 @@ export async function makeSwingsetController(
FinalizationRegistry,
};

const kernelOptions = { verbose, testTrackDecref, defaultManagerType };
const kernelOptions = { verbose, testTrackDecref };
const kernel = buildKernel(kernelEndowments, deviceEndowments, kernelOptions);

if (runtimeOptions.verbose) {
Expand Down Expand Up @@ -324,14 +323,12 @@ export async function buildVatController(
debugPrefix,
slogCallbacks,
testTrackDecref,
defaultManagerType,
} = runtimeOptions;
const actualRuntimeOptions = {
verbose,
debugPrefix,
testTrackDecref,
slogCallbacks,
defaultManagerType,
};
const initializationOptions = { verbose, kernelBundles };
let bootstrapResult;
Expand Down
24 changes: 21 additions & 3 deletions packages/SwingSet/src/initializeSwingset.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global require */
/* global require, process */
// @ts-check
import fs from 'fs';
import path from 'path';
Expand Down Expand Up @@ -75,6 +75,7 @@ function byName(a, b) {
/**
* @typedef {Object} SwingSetConfig a swingset config object
* @property {string} [bootstrap]
* @property { ManagerType } [defaultManagerType]
* @property {SwingSetConfigDescriptor} [vats]
* @property {SwingSetConfigDescriptor} [bundles]
* @property {*} [devices]
Expand Down Expand Up @@ -212,7 +213,6 @@ function normalizeConfigDescriptor(desc, dirname, expectParameters) {
*/
export function loadSwingsetConfigFile(configPath) {
try {
/** @type { SwingSetConfig } */
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
const dirname = path.dirname(configPath);
normalizeConfigDescriptor(config.vats, dirname, true);
Expand All @@ -238,17 +238,18 @@ export function swingsetIsInitialized(storage) {
}

/**
*
* @param {SwingSetConfig} config
* @param {string[]} argv
* @param {*} hostStorage
* @param {{ kernelBundles?: Record<string, string> }} initializationOptions
* @param {{ env?: Record<string, string> }} runtimeOptions
*/
export async function initializeSwingset(
config,
argv = [],
hostStorage = initSwingStore().storage,
initializationOptions = {},
runtimeOptions = {},
) {
insistStorageAPI(hostStorage);

Expand All @@ -269,6 +270,23 @@ export async function initializeSwingset(
config.devices = {};
}

// Use ambient process.env only if caller did not specify.
const { env: { WORKER_TYPE } = process.env } = runtimeOptions;
const defaultManagerType = config.defaultManagerType || WORKER_TYPE;
switch (defaultManagerType) {
case 'local':
case 'nodeWorker':
case 'node-subprocess':
case 'xs-worker':
config.defaultManagerType = defaultManagerType;
break;
case undefined:
config.defaultManagerType = 'local';
break;
default:
assert.fail(X`unknown manager type ${defaultManagerType}`);
}

const { kernelBundles = await buildKernelBundles() } = initializationOptions;

hostStorage.set('kernelBundle', JSON.stringify(kernelBundles.kernel));
Expand Down
5 changes: 4 additions & 1 deletion packages/SwingSet/src/kernel/initializeKernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function initializeKernel(config, hostStorage, verbose = false) {

const wasInitialized = kernelKeeper.getInitialized();
assert(!wasInitialized);
kernelKeeper.createStartingKernelState();
kernelKeeper.createStartingKernelState(config.defaultManagerType || 'local');

if (config.bundles) {
for (const name of Object.keys(config.bundles)) {
Expand Down Expand Up @@ -68,6 +68,9 @@ export function initializeKernel(config, hostStorage, verbose = false) {
creationOptions.vatParameters = vatParameters;
creationOptions.description = `static name=${name}`;
creationOptions.name = name;
if (!creationOptions.managerType) {
creationOptions.managerType = kernelKeeper.getDefaultManagerType();
}

const vatID = kernelKeeper.allocateVatIDForNameIfNeeded(name);
logStartup(`assigned VatID ${vatID} for genesis vat ${name}`);
Expand Down
6 changes: 6 additions & 0 deletions packages/SwingSet/src/kernel/loadVat.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ export function makeVatLoader(stuff) {
const vatID = allocateUnusedVatID();
kernelKeeper.addDynamicVatID(vatID);
const vatKeeper = kernelKeeper.allocateVatKeeper(vatID);
if (!dynamicOptions.managerType) {
dynamicOptions = {
...dynamicOptions,
managerType: kernelKeeper.getDefaultManagerType(),
};
}
vatKeeper.setSourceAndOptions(source, dynamicOptions);
// eslint-disable-next-line no-use-before-define
create(vatID, source, dynamicOptions, true, true);
Expand Down
11 changes: 10 additions & 1 deletion packages/SwingSet/src/kernel/state/kernelKeeper.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,10 @@ export default function makeKernelKeeper(storage, kernelSlog) {
storage.set('crankNumber', `${crankNumber + 1n}`);
}

function createStartingKernelState() {
/**
* @param { ManagerType } defaultManagerType
*/
function createStartingKernelState(defaultManagerType) {
storage.set('vat.names', '[]');
storage.set('vat.dynamicIDs', '[]');
storage.set('vat.nextID', `${FIRST_VAT_ID}`);
Expand All @@ -209,6 +212,11 @@ export default function makeKernelKeeper(storage, kernelSlog) {
storage.set('kp.nextID', `${FIRST_PROMISE_ID}`);
storage.set('runQueue', JSON.stringify([]));
storage.set('crankNumber', `${FIRST_CRANK_NUMBER}`);
storage.set('kernel.defaultManagerType', defaultManagerType);
}

function getDefaultManagerType() {
return getRequired('kernel.defaultManagerType');
}

function addBundle(name, bundle) {
Expand Down Expand Up @@ -819,6 +827,7 @@ export default function makeKernelKeeper(storage, kernelSlog) {
getInitialized,
setInitialized,
createStartingKernelState,
getDefaultManagerType,
addBundle,
getBundle,

Expand Down
2 changes: 2 additions & 0 deletions packages/SwingSet/src/kernel/state/vatKeeper.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ export function makeVatKeeper(
insistVatID(vatID);

function setSourceAndOptions(source, options) {
// take care with API change
assert(options.managerType, X`vat options missing managerType`);
assert.typeof(source, 'object');
assert(source.bundle || source.bundleName);
assert.typeof(options, 'object');
Expand Down
3 changes: 2 additions & 1 deletion packages/SwingSet/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
* TODO: metered...
*
* See validateManagerOptions() in factory.js
* @typedef { 'local' | 'nodeWorker' | 'node-subprocess' | 'xs-worker' } ManagerType
* @typedef {{
* managerType: 'local' | 'nodeWorker' | 'node-subprocess' | 'xs-worker',
* managerType: ManagerType,
* metered?: boolean,
* enableInternalMetering?: boolean,
* enableDisavow?: boolean,
Expand Down
33 changes: 32 additions & 1 deletion packages/SwingSet/test/test-controller.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* global require __dirname */
// eslint-disable-next-line import/order
import { test } from '../tools/prepare-test-env-ava';

// eslint-disable-next-line import/order
import path from 'path';
import { initSwingStore } from '@agoric/swing-store-simple';
import { buildVatController, loadBasedir } from '../src/index';
import { checkKT } from './util';

Expand Down Expand Up @@ -94,6 +95,36 @@ test('bootstrap', async t => {
t.deepEqual(c.dump().log, ['bootstrap called']);
});

test('XS bootstrap', async t => {
const config = await loadBasedir(
path.resolve(__dirname, 'basedir-controller-2'),
);
config.defaultManagerType = 'xs-worker';
const hostStorage = initSwingStore().storage;
const c = await buildVatController(config, [], { hostStorage });
t.deepEqual(c.dump().log, ['bootstrap called']);
t.is(
hostStorage.get('kernel.defaultManagerType'),
'xs-worker',
'defaultManagerType is saved by kernelKeeper',
);
const vatID = c.vatNameToID('bootstrap');
const options = JSON.parse(hostStorage.get(`${vatID}.options`));
t.is(
options.managerType,
'xs-worker',
'managerType gets recorded for the bootstrap vat',
);
});

test('validate config.defaultManagerType', async t => {
const config = await loadBasedir(
path.resolve(__dirname, 'basedir-controller-2'),
);
config.defaultManagerType = 'XYZ';
await t.throwsAsync(buildVatController(config), { message: /XYZ/ });
});

test('bootstrap export', async t => {
const config = await loadBasedir(
path.resolve(__dirname, 'basedir-controller-3'),
Expand Down
10 changes: 10 additions & 0 deletions packages/SwingSet/test/test-kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -1229,3 +1229,13 @@ test('pipelined promise queueing', async t => {
},
]);
});

test('xs-worker default manager type', async t => {
const endowments = makeEndowments();
initializeKernel({ defaultManagerType: 'xs-worker' }, endowments.hostStorage);
buildKernel(endowments, {}, {});
t.deepEqual(
endowments.hostStorage.get('kernel.defaultManagerType'),
'xs-worker',
);
});
27 changes: 19 additions & 8 deletions packages/SwingSet/test/test-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ test('kernel state', async t => {
const { kstorage, getState, commitCrank } = buildKeeperStorageInMemory();
const k = makeKernelKeeper(kstorage);
t.truthy(!k.getInitialized());
k.createStartingKernelState();
k.createStartingKernelState('local');
k.setInitialized();

commitCrank();
Expand All @@ -287,13 +287,14 @@ test('kernel state', async t => {
['ko.nextID', '20'],
['kd.nextID', '30'],
['kp.nextID', '40'],
['kernel.defaultManagerType', 'local'],
]);
});

test('kernelKeeper vat names', async t => {
const { kstorage, getState, commitCrank } = buildKeeperStorageInMemory();
const k = makeKernelKeeper(kstorage);
k.createStartingKernelState();
k.createStartingKernelState('local');

const v1 = k.allocateVatIDForNameIfNeeded('vatname5');
const v2 = k.allocateVatIDForNameIfNeeded('Frank');
Expand All @@ -314,6 +315,7 @@ test('kernelKeeper vat names', async t => {
['kp.nextID', '40'],
['vat.name.vatname5', 'v1'],
['vat.name.Frank', 'v2'],
['kernel.defaultManagerType', 'local'],
]);
t.deepEqual(k.getStaticVats(), [
['Frank', 'v2'],
Expand All @@ -334,7 +336,7 @@ test('kernelKeeper vat names', async t => {
test('kernelKeeper device names', async t => {
const { kstorage, getState, commitCrank } = buildKeeperStorageInMemory();
const k = makeKernelKeeper(kstorage);
k.createStartingKernelState();
k.createStartingKernelState('local');

const d7 = k.allocateDeviceIDForNameIfNeeded('devicename5');
const d8 = k.allocateDeviceIDForNameIfNeeded('Frank');
Expand All @@ -355,6 +357,7 @@ test('kernelKeeper device names', async t => {
['kp.nextID', '40'],
['device.name.devicename5', 'd7'],
['device.name.Frank', 'd8'],
['kernel.defaultManagerType', 'local'],
]);
t.deepEqual(k.getDevices(), [
['Frank', 'd8'],
Expand All @@ -375,7 +378,7 @@ test('kernelKeeper device names', async t => {
test('kernelKeeper runQueue', async t => {
const { kstorage, getState, commitCrank } = buildKeeperStorageInMemory();
const k = makeKernelKeeper(kstorage);
k.createStartingKernelState();
k.createStartingKernelState('local');

t.truthy(k.isRunQueueEmpty());
t.is(k.getRunQueueLength(), 0);
Expand Down Expand Up @@ -411,7 +414,7 @@ test('kernelKeeper runQueue', async t => {
test('kernelKeeper promises', async t => {
const { kstorage, getState, commitCrank } = buildKeeperStorageInMemory();
const k = makeKernelKeeper(kstorage);
k.createStartingKernelState();
k.createStartingKernelState('local');

const p1 = k.addKernelPromiseForVat('v4');
t.deepEqual(k.getKernelPromise(p1), {
Expand Down Expand Up @@ -519,13 +522,14 @@ test('kernelKeeper promises', async t => {
['kp40.data.slots', 'ko44'],
['kp40.state', 'fulfilled'],
['kp40.refCount', '0'],
['kernel.defaultManagerType', 'local'],
]);
});

test('kernelKeeper promise resolveToData', async t => {
const { kstorage } = buildKeeperStorageInMemory();
const k = makeKernelKeeper(kstorage);
k.createStartingKernelState();
k.createStartingKernelState('local');

const p1 = k.addKernelPromiseForVat('v4');
const capdata = harden({
Expand All @@ -546,7 +550,7 @@ test('kernelKeeper promise resolveToData', async t => {
test('kernelKeeper promise reject', async t => {
const { kstorage } = buildKeeperStorageInMemory();
const k = makeKernelKeeper(kstorage);
k.createStartingKernelState();
k.createStartingKernelState('local');

const p1 = k.addKernelPromiseForVat('v4');
const capdata = harden({
Expand All @@ -567,7 +571,7 @@ test('kernelKeeper promise reject', async t => {
test('vatKeeper', async t => {
const { kstorage, getState, commitCrank } = buildKeeperStorageInMemory();
const k = makeKernelKeeper(kstorage);
k.createStartingKernelState();
k.createStartingKernelState('local');

const v1 = k.allocateVatIDForNameIfNeeded('name1');
const vk = k.allocateVatKeeper(v1);
Expand Down Expand Up @@ -595,3 +599,10 @@ test('vatKeeper', async t => {
t.is(vk2.mapKernelSlotToVatSlot(kernelImport2), vatImport2);
t.is(vk2.mapVatSlotToKernelSlot(vatImport2), kernelImport2);
});

test('XS vatKeeper defaultManagerType', async t => {
const { kstorage } = buildKeeperStorageInMemory();
const k = makeKernelKeeper(kstorage);
k.createStartingKernelState('xs-worker');
t.is(k.getDefaultManagerType(), 'xs-worker');
});

0 comments on commit 973b403

Please sign in to comment.