From feda6c8510f56385c2becec40412223b4acf109d Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Sat, 17 Jul 2021 11:40:33 -0600 Subject: [PATCH] fix(captp): ensure trapcap reply iteration is serial --- packages/captp/src/captp.js | 45 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/packages/captp/src/captp.js b/packages/captp/src/captp.js index aaf9efb3992..1762c0ad5ba 100644 --- a/packages/captp/src/captp.js +++ b/packages/captp/src/captp.js @@ -443,31 +443,30 @@ export const makeCapTP = ( const [method, args] = unserialize(serialized); - const resultPK = makePromiseKit(); - trapIteratorResultP.set(questionID, resultPK.promise); + const getNextResultP = async () => { + const result = await resultP; + if (!result || result.done) { + // We're done! + trapIterator.delete(questionID); + trapIteratorResultP.delete(questionID); + return result; + } - const { done } = await resultP; - if (done) { - trapIterator.delete(questionID); - return; - } - const ait = trapIterator.get(questionID); - - try { - switch (method) { - case 'next': - case 'return': - case 'throw': { - resultPK.resolve(ait && ait[method] && ait[method](...args)); - break; - } - default: { - assert.fail(X`Unrecognized iteration method ${method}`); - } + const ait = trapIterator.get(questionID); + if (ait && ait[method]) { + // Drive the next iteration. + return ait[method](...args); } - } catch (e) { - resultPK.reject(e); - } + + return result; + }; + + // Store the next result promise. + const nextResultP = getNextResultP(); + trapIteratorResultP.set(questionID, nextResultP); + + // Wait for the next iteration so that we properly report errors. + await nextResultP; }, // Answer to one of our questions. async CTP_RETURN(obj) {