Skip to content

Commit d500bf9

Browse files
committed
fix(pipelining): enable pipelining of GET, POST
Closes #2
1 parent c077dbe commit d500bf9

File tree

1 file changed

+42
-29
lines changed

1 file changed

+42
-29
lines changed

lib/captp.js

+42-29
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ export function makeCapTP(ourId, send, bootstrapObj = undefined) {
2121
let lastQuestionID = 0;
2222

2323
const valToSlot = new WeakMap();
24-
const slotToVal = new Map(); // exports, answers
24+
const slotToVal = new Map(); // exports
2525
const questions = new Map(); // chosen by us
26+
const answers = new Map(); // chosen by our peer
2627
const imports = new Map(); // chosen by our peer
2728

2829
function serializeSlot(val, slots, slotMap) {
@@ -70,23 +71,33 @@ export function makeCapTP(ourId, send, bootstrapObj = undefined) {
7071
});
7172
}
7273

73-
function makeRemote(slot) {
74+
function makeQuestion() {
75+
lastQuestionID += 1;
76+
const questionID = lastQuestionID;
77+
const pr = makeRemote(questionID);
78+
questions.set(questionID, pr);
79+
return [questionID, pr];
80+
}
81+
82+
function makeRemote(target) {
7483
const handler = {
84+
GET(_o, prop) {
85+
const [questionID, pr] = makeQuestion();
86+
send({
87+
type: 'CTP_CALL',
88+
questionID,
89+
target,
90+
method: serialize(harden([prop])),
91+
});
92+
return harden(pr.p);
93+
},
7594
POST(_o, prop, args) {
7695
// Support: o~.[prop](...args) remote method invocation
77-
// FIXME: Implement a HandledPromise here to support pipelining.
78-
const pr = {};
79-
pr.p = new Promise((resolve, reject) => {
80-
pr.res = resolve;
81-
pr.rej = reject;
82-
});
83-
lastQuestionID += 1;
84-
const questionID = lastQuestionID;
85-
questions.set(questionID, pr);
96+
const [questionID, pr] = makeQuestion();
8697
send({
8798
type: 'CTP_CALL',
8899
questionID,
89-
target: slot,
100+
target,
90101
method: serialize(harden([prop, args])),
91102
});
92103
return harden(pr.p);
@@ -131,6 +142,7 @@ export function makeCapTP(ourId, send, bootstrapObj = undefined) {
131142
const bootstrap =
132143
typeof bootstrapObj === 'function' ? bootstrapObj() : bootstrapObj;
133144
// console.log('sending bootstrap', bootstrap);
145+
answers.set(questionID, bootstrap);
134146
send({
135147
type: 'CTP_RETURN',
136148
answerID: questionID,
@@ -140,15 +152,23 @@ export function makeCapTP(ourId, send, bootstrapObj = undefined) {
140152
CTP_CALL(obj) {
141153
const { questionID, target } = obj;
142154
const [prop, args] = unserialize(obj.method);
143-
const val = unserialize({
144-
body: JSON.stringify({
145-
[QCLASS]: 'slot',
146-
index: 0,
147-
}),
148-
slots: [target],
149-
});
150-
HandledPromise.applyMethod(val, prop, args)
151-
.then(res =>
155+
let val;
156+
if (answers.has(target)) {
157+
val = answers.get(target);
158+
} else {
159+
val = unserialize({
160+
body: JSON.stringify({
161+
[QCLASS]: 'slot',
162+
index: 0,
163+
}),
164+
slots: [target],
165+
});
166+
}
167+
const hp = args
168+
? HandledPromise.applyMethod(val, prop, args)
169+
: HandledPromise.get(val, prop);
170+
answers.set(questionID, hp);
171+
hp.then(res =>
152172
send({
153173
type: 'CTP_RETURN',
154174
answerID: questionID,
@@ -198,14 +218,7 @@ export function makeCapTP(ourId, send, bootstrapObj = undefined) {
198218

199219
// Get a reference to the other side's bootstrap object.
200220
const getBootstrap = () => {
201-
const pr = {};
202-
pr.p = new Promise((resolve, reject) => {
203-
pr.res = resolve;
204-
pr.rej = reject;
205-
});
206-
lastQuestionID += 1;
207-
const questionID = lastQuestionID;
208-
questions.set(questionID, pr);
221+
const [questionID, pr] = makeQuestion();
209222
send({
210223
type: 'CTP_BOOTSTRAP',
211224
questionID,

0 commit comments

Comments
 (0)