Skip to content

Commit

Permalink
refactor: Move DisconnectionObject generation/testing into "internal"
Browse files Browse the repository at this point in the history
  • Loading branch information
gibson042 committed Apr 13, 2023
1 parent d6c40e9 commit c022a5d
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 15 deletions.
10 changes: 5 additions & 5 deletions packages/SwingSet/src/kernel/kernel.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { assert, Fail } from '@agoric/assert';
import { isNat } from '@endo/nat';
import { importBundle } from '@endo/import-bundle';
import { makeUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';
import { assertKnownOptions } from '../lib/assertOptions.js';
import { foreverPolicy } from '../lib/runPolicies.js';
import { kser, kslot, makeError } from '../lib/kmarshal.js';
Expand Down Expand Up @@ -825,12 +826,11 @@ export default function buildKernel(
const { meterID } = vatInfo;
let computrons;
const vatKeeper = kernelKeeper.provideVatKeeper(vatID);
const disconnectObject = {
name: 'vatUpgraded',
const disconnectionObject = makeUpgradeDisconnection(
upgradeMessage,
incarnationNumber: vatKeeper.getIncarnationNumber(),
};
const disconnectionCapData = kser(disconnectObject);
vatKeeper.getIncarnationNumber(),
);
const disconnectionCapData = kser(disconnectionObject);

/**
* Terminate the vat and translate internal-delivery results into
Expand Down
2 changes: 1 addition & 1 deletion packages/SwingSet/src/types-external.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export {};
* @typedef { import('@agoric/swingset-liveslots').Message } Message
*
* @typedef { 'none' | 'ignore' | 'logAlways' | 'logFailure' | 'panic' } ResolutionPolicy
* @typedef {{ name: string, upgradeMessage: string, incarnationNumber: number }} DisconnectObject
* @typedef {import('@agoric/internal/src/upgrade-api.js').DisconnectionObject} DisconnectionObject
*
* @typedef { import('@agoric/swingset-liveslots').VatDeliveryObject } VatDeliveryObject
* @typedef { import('@agoric/swingset-liveslots').VatOneResolution } VatOneResolution
Expand Down
41 changes: 41 additions & 0 deletions packages/internal/src/upgrade-api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// @ts-check
// @jessie-check
import { isObject } from '@endo/marshal';

/**
* @typedef {{ name: string, upgradeMessage: string, incarnationNumber: number }} DisconnectionObject
*/

/**
* Makes an Error-like object for use as the rejection value of promises
* abandoned by upgrade.
*
* @param {string} upgradeMessage
* @param {number} toIncarnationNumber
* @returns {DisconnectionObject}
*/
export const makeUpgradeDisconnection = (upgradeMessage, toIncarnationNumber) =>
harden({
name: 'vatUpgraded',
upgradeMessage,
incarnationNumber: toIncarnationNumber,
});
harden(makeUpgradeDisconnection);

// TODO: Simplify once we have @endo/patterns (or just export the shape).
// const upgradeDisconnectionShape = harden({
// name: 'vatUpgraded',
// upgradeMessage: M.string(),
// incarnationNumber: M.number(),
// });
// const isUpgradeDisconnection = err => matches(err, upgradeDisconnectionShape);
/**
* @param {any} err
* @returns {err is DisconnectionObject}
*/
export const isUpgradeDisconnection = err =>
isObject(err) &&
err.name === 'vatUpgraded' &&
typeof err.upgradeMessage === 'string' &&
typeof err.incarnationNumber === 'number';
harden(isUpgradeDisconnection);
21 changes: 21 additions & 0 deletions packages/internal/test/test-upgrade-api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @ts-check
import '@endo/init';
import test from 'ava';
import {
makeUpgradeDisconnection,
isUpgradeDisconnection,
} from '../src/upgrade-api.js';

test('isUpgradeDisconnection must recognize disconnection objects', t => {
const disconnection = makeUpgradeDisconnection('vat upgraded', 2);
t.true(isUpgradeDisconnection(disconnection));
});

test('isUpgradeDisconnection must recognize original-format disconnection objects', t => {
const disconnection = harden({
name: 'vatUpgraded',
upgradeMessage: 'vat upgraded',
incarnationNumber: 2,
});
t.true(isUpgradeDisconnection(disconnection));
});
13 changes: 4 additions & 9 deletions packages/notifier/src/subscribe.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { E, Far } from '@endo/far';
import { isObject } from '@endo/marshal';
import { isNat } from '@endo/nat';
import { isUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';

import './types-ambient.js';

Expand All @@ -15,7 +14,7 @@ const sink = () => {};
* @returns {Promise<T>}
*/
const reconnectAsNeeded = async thunk => {
let lastVersion;
let lastVersion = -Infinity;
// End synchronous prelude.
await null;
for (;;) {
Expand All @@ -24,13 +23,9 @@ const reconnectAsNeeded = async thunk => {
const result = await thunk();
return result;
} catch (err) {
/** @see processUpgrade in {@link ../../SwingSet/src/kernel/kernel.js} */
if (isObject(err) && err.name === 'vatUpgraded') {
if (isUpgradeDisconnection(err)) {
const { incarnationNumber: version } = err;
if (
isNat(version) &&
(lastVersion === undefined || version > lastVersion)
) {
if (version > lastVersion) {
// We don't expect another upgrade in between receiving
// a disconnection and re-requesting an update, but must
// nevertheless be prepared for that.
Expand Down

0 comments on commit c022a5d

Please sign in to comment.