Skip to content

Commit

Permalink
Merge pull request #8659 from Agoric/mfig-run-utils-js
Browse files Browse the repository at this point in the history
refactor(SwingSet): convert `run-utils.ts` to JS
  • Loading branch information
mergify[bot] authored Dec 14, 2023
2 parents 43543c3 + bcda21c commit d61be8d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 65 deletions.
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
/* eslint-disable @jessie.js/safe-await-separator */
import { Fail, q } from '@agoric/assert';
import { kunser } from '@agoric/kmarshal';
import { makeQueue } from '@endo/stream';
import type { E } from '@endo/eventual-send';

import type { SwingsetController } from '../src/controller/controller.js';

const sink = () => {};

export const makeRunUtils = (
controller: SwingsetController,
log = (..._) => {},
) => {
/**
* @param {import('../src/controller/controller.js').SwingsetController} controller
* @param {(...args: any[]) => void} [log]
*/
export const makeRunUtils = (controller, log = (..._) => {}) => {
let cranksRun = 0;

const mutex = makeQueue();

mutex.put(controller.run());

const runThunk = async <T extends () => any>(
thunk: T,
): Promise<ReturnType<T>> => {
try {
// this promise for the last lock may fail
await mutex.get();
} catch {
// noop because the result will resolve for the previous runMethod return
}
/**
* @template {() => any} T
* @param {T} thunk
* @returns {Promise<ReturnType<T>>}
*/
const runThunk = async thunk => {
// this promise for the last lock may fail
// sink because the result will resolve for the previous runMethod return
await mutex.get().catch(sink);

const thunkResult = await thunk();

Expand Down Expand Up @@ -60,10 +57,12 @@ export const makeRunUtils = (
}
};

type EVProxy = typeof E & {
sendOnly: (presence: unknown) => Record<string, (...args: any) => void>;
vat: (name: string) => Record<string, (...args: any) => Promise<any>>;
};
/**
* @typedef {import('@endo/eventual-send').EProxy & {
* sendOnly: (presence: unknown) => Record<string, (...args: any) => void>;
* vat: (name: string) => Record<string, (...args: any) => Promise<any>>;
* }} EVProxy
*/

// IMPORTANT WARNING TO USERS OF `EV`
//
Expand Down Expand Up @@ -109,48 +108,56 @@ export const makeRunUtils = (
// promise that can remain pending indefinitely, possibly to be settled by a
// future message delivery.

/** @type {EVProxy} */
// @ts-expect-error cast, approximate
const EV: EVProxy = presence =>
new Proxy(harden({}), {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(() =>
controller.queueToVatObject(presence, method, args),
);
return harden(boundMethod);
},
});
EV.vat = vatName =>
new Proxy(harden({}), {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(() => controller.queueToVatRoot(vatName, method, args));
return harden(boundMethod);
},
});
// @ts-expect-error xxx
EV.sendOnly = presence =>
new Proxy(harden({}), {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(
() => controller.queueToVatObject(presence, method, args),
true,
);
return harden(boundMethod);
},
});
// @ts-expect-error xxx
EV.get = presence =>
new Proxy(harden({}), {
get: (_t, pathElement, _rx) =>
queueAndRun(() =>
controller.queueToVatRoot('bootstrap', 'awaitVatObject', [
presence,
[pathElement],
]),
),
});
const EV = Object.assign(
presence =>
new Proxy(harden({}), {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(() =>
controller.queueToVatObject(presence, method, args),
);
return harden(boundMethod);
},
}),
{
vat: vatName =>
new Proxy(harden({}), {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(() =>
controller.queueToVatRoot(vatName, method, args),
);
return harden(boundMethod);
},
}),
sendOnly: presence =>
new Proxy(harden({}), {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(
() => controller.queueToVatObject(presence, method, args),
true,
);
return harden(boundMethod);
},
}),
get: presence =>
new Proxy(harden({}), {
get: (_t, pathElement, _rx) =>
queueAndRun(() =>
controller.queueToVatRoot('bootstrap', 'awaitVatObject', [
presence,
[pathElement],
]),
),
}),
},
);
return harden({ runThunk, EV });
};
export type RunUtils = ReturnType<typeof makeRunUtils>;

/**
* @typedef {ReturnType<typeof makeRunUtils>} RunUtils
*/
2 changes: 1 addition & 1 deletion packages/boot/test/upgrading/test-upgrade-vats.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { test as anyTest } from '@agoric/swingset-vat/tools/prepare-test-env-ava

import { BridgeId } from '@agoric/internal';
import { buildVatController } from '@agoric/swingset-vat';
import { makeRunUtils } from '@agoric/swingset-vat/tools/run-utils.ts';
import { makeRunUtils } from '@agoric/swingset-vat/tools/run-utils.js';
import { resolve as importMetaResolve } from 'import-meta-resolve';
import { matchAmount, matchIter, matchRef } from '../../tools/supports.ts';

Expand Down
2 changes: 1 addition & 1 deletion packages/boot/tools/drivers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type { WalletFactoryStartResult } from '@agoric/vats/src/core/startWallet
import type { OfferSpec } from '@agoric/smart-wallet/src/offers.js';
import type { TimerService } from '@agoric/time';
import type { OfferMaker } from '@agoric/smart-wallet/src/types.js';
import type { RunUtils } from '@agoric/swingset-vat/tools/run-utils.ts';
import type { RunUtils } from '@agoric/swingset-vat/tools/run-utils.js';
import type { SwingsetTestKit } from './supports.ts';

export const makeWalletFactoryDriver = async (
Expand Down

0 comments on commit d61be8d

Please sign in to comment.