Skip to content

Commit

Permalink
Merge branch '131-liveslots-pipeline'
Browse files Browse the repository at this point in the history
  • Loading branch information
warner committed Sep 6, 2019
2 parents 8e3d62f + 6d98cab commit a8fe25d
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 22 deletions.
34 changes: 16 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
},
"dependencies": {
"@agoric/acorn-infix-bang": "0.0.4",
"@agoric/default-evaluate-options": "^0.1.2",
"@agoric/default-evaluate-options": "^0.1.3",
"@agoric/evaluate": "^1.3.2",
"@agoric/harden": "^0.0.4",
"@agoric/marshal": "0.0.1",
Expand Down
5 changes: 2 additions & 3 deletions src/kernel/liveSlots.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import harden from '@agoric/harden';
import Nat from '@agoric/nat';
import { QCLASS, mustPassByPresence, makeMarshal } from '@agoric/marshal';
import makePromise from './makePromise';

// 'makeLiveSlots' is a dispatcher which uses javascript Maps to keep track
// of local objects which have been exported. These cannot be persisted
Expand Down Expand Up @@ -199,11 +198,12 @@ function build(syscall, _state, makeRoot, forVatID) {
const m = makeMarshal(serializeSlot, unserializeSlot);

function queueMessage(targetSlot, prop, args) {
const done = makePromise();
const ser = m.serialize(harden({ args }));
lsdebug(`ls.qm send(${JSON.stringify(targetSlot)}, ${prop}`);
const promiseID = syscall.send(targetSlot, prop, ser.argsString, ser.slots);
lsdebug(` ls.qm got promiseID ${promiseID}`);
const slot = { type: 'promise', id: promiseID };
const done = makeQueued(slot);

// prepare for notifyFulfillToData/etc
importedPromisesByPromiseID.set(promiseID, done);
Expand All @@ -215,7 +215,6 @@ function build(syscall, _state, makeRoot, forVatID) {

// prepare the serializer to recognize it, if it's used as an argument or
// return value
const slot = { type: 'promise', id: promiseID };
const key = slotToKey(slot);
valToSlot.set(done.p, slot);
slotKeyToVal.set(key, done.p);
Expand Down
71 changes: 71 additions & 0 deletions test/test-liveslots.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// eslint-disable-next-line no-redeclare
/* global setImmediate */
import { test } from 'tape-promise/tape';
import harden from '@agoric/harden';
// eslint-disable-next-line no-unused-vars
import evaluateExpr from '@agoric/evaluate'; // to get Promise.makeHandled
import buildKernel from '../src/kernel/index';
import { makeLiveSlots } from '../src/kernel/liveSlots';

test('liveslots pipelines to syscall.send', async t => {
const kernel = buildKernel({ setImmediate });
const log = [];

function setupA(syscallA, state, helpers) {
function build(E, _D) {
return harden({
one(x) {
const p1 = E(x).pipe1();
const p2 = E(p1).pipe2();
E(p2).pipe3();
log.push('sent p1p2p3');
},
});
}
return makeLiveSlots(syscallA, state, build, helpers.vatID);
}
kernel.addGenesisVat('a', setupA);

let syscall;
function setupB(syscallB, _state, _helpers) {
syscall = syscallB;
function deliver() {}
return { deliver };
}
kernel.addGenesisVat('b', setupB);

await kernel.start(); // no bootstrap
t.deepEqual(kernel.dump().runQueue, []);

const root = kernel.addImport(
'b',
harden({ type: 'export', vatID: 'a', id: 0 }),
);

// root!one(x) // sendOnly
const arg0 = JSON.stringify({ args: [{ '@qclass': 'slot', index: 0 }] });
syscall.send(root, 'one', arg0, [harden({ type: 'export', id: 5 })]);

// calling one() should cause three syscall.send() calls to be made: one
// for x!pipe1(), a second pipelined to the result promise of it, and a
// third pipelined to the result of the second. With the current design,
// the kernel ought to put the first onto the runQueue, and second onto the
// kernel promise queue for the result of the first, and likewise the
// third.
await kernel.step();
const resolverID = kernel.dump().runQueue[0].msg.kernelResolverID;
const state = JSON.parse(kernel.getState());
const kp = state.kernelPromises[resolverID];
t.equal(kp.queue.length, 1);
t.equal(kp.queue[0].method, 'pipe2');
const resolverID2 = kp.queue[0].kernelResolverID;
const kp2 = state.kernelPromises[resolverID2];
t.equal(kp2.queue.length, 1);
t.equal(kp2.queue[0].method, 'pipe3');

// in the new design, three sends() mean three items on the runqueue, and
// they'll be appended to kernel promise queues after they get to the front
// t.deepEqual(kernel.dump().runQueue.length, 3);

t.end();
});

0 comments on commit a8fe25d

Please sign in to comment.