From 79a930a6c1d0ce9825541675b6eeed5190aa69c1 Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Fri, 18 Oct 2019 19:30:09 -0600 Subject: [PATCH] feat(disconnected): function to break all pending promises --- lib/captp.js | 17 ++++++++++++++++- test/disco.js | 15 +++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 test/disco.js diff --git a/lib/captp.js b/lib/captp.js index 31f68778524..0fe02c70d1b 100644 --- a/lib/captp.js +++ b/lib/captp.js @@ -8,6 +8,7 @@ import { HandledPromise, E } from '@agoric/eventual-send'; export { E, HandledPromise, Nat, harden }; export function makeCapTP(ourId, send, bootstrapObj = undefined) { + let unplug = false; const { serialize, unserialize } = makeMarshal( // eslint-disable-next-line no-use-before-define serializeSlot, @@ -204,6 +205,9 @@ export function makeCapTP(ourId, send, bootstrapObj = undefined) { // Return a dispatch function. const dispatch = obj => { + if (unplug) { + return false; + } const fn = handler[obj.type]; if (fn) { fn(obj); @@ -212,5 +216,16 @@ export function makeCapTP(ourId, send, bootstrapObj = undefined) { return false; }; - return harden({ dispatch, getBootstrap }); + const disconnected = () => { + unplug = true; + const err = Error(`${ourId} disconnected`); + for (const pr of questions.values()) { + pr.rej(err); + } + for (const pr of imports.values()) { + pr.rej(err); + } + }; + + return harden({ dispatch, getBootstrap, disconnected }); } diff --git a/test/disco.js b/test/disco.js new file mode 100644 index 00000000000..6e9383adef6 --- /dev/null +++ b/test/disco.js @@ -0,0 +1,15 @@ +import { test } from 'tape-promise/tape'; +import { harden, makeCapTP } from '../lib/captp'; + +test('try disconnecting captp', async t => { + try { + const { dispatch, getBootstrap, disconnected } = makeCapTP('us', obj => {}, () => harden({})); + const pr = t.rejects(getBootstrap(), Error, 'rejected after disconnect'); + disconnected(); + await pr; + } catch (e) { + t.isNot(e, e, 'unexpected exception'); + } finally { + t.end(); + } +});