MCPcopy
hub / github.com/cloudflare/capnweb / ensureResolvingExport

Method ensureResolvingExport

src/rpc.ts:569–634  ·  view source on GitHub ↗
(exportId: ExportId)

Source from the content-addressed store, hash-verified

567 }
568
569 private ensureResolvingExport(exportId: ExportId) {
570 let exp = this.exports[exportId];
571 if (!exp) {
572 throw new Error(`no such export ID: ${exportId}`);
573 }
574 if (!exp.pull) {
575 let resolve = async () => {
576 let hook = exp.hook;
577 for (;;) {
578 let payload = await hook.pull();
579 if (payload.value instanceof RpcStub) {
580 let {hook: inner, pathIfPromise} = unwrapStubAndPath(payload.value);
581 if (pathIfPromise && pathIfPromise.length == 0) {
582 if (this.getImport(hook) === undefined) {
583 // Optimization: The resolution is just another promise, and it is not a promise
584 // pointing back to the peer. So if we send a resolve message, it's just going to
585 // resolve to another new promise export, which is just going to have to wait for
586 // another resolve message later. This intermediate resolve message gives the peer
587 // no useful information, so let's skip it and just wait for the chained
588 // resolution.
589 hook = inner;
590 continue;
591 }
592 }
593 }
594
595 return payload;
596 }
597 };
598
599 let autoRelease = exp.autoRelease;
600
601 ++this.pullCount;
602 exp.pull = resolve().then(
603 payload => {
604 // We don't transfer ownership of stubs in the payload since the payload
605 // belongs to the hook which sticks around to handle pipelined requests.
606 let value = Devaluator.devaluate(payload.value, undefined, this, payload, this.encodingLevel);
607 this.send(["resolve", exportId, value]);
608 if (autoRelease) this.releaseExport(exportId, 1);
609 },
610 error => {
611 this.send(["reject", exportId, Devaluator.devaluate(error, undefined, this, undefined, this.encodingLevel)]);
612 if (autoRelease) this.releaseExport(exportId, 1);
613 }
614 ).catch(
615 error => {
616 // If serialization failed, report the serialization error, which should
617 // itself always be serializable.
618 try {
619 this.send(["reject", exportId, Devaluator.devaluate(error, undefined, this, undefined, this.encodingLevel)]);
620 if (autoRelease) this.releaseExport(exportId, 1);
621 } catch (error2) {
622 // TODO: Shouldn't happen, now what?
623 this.abort(error2);
624 }
625 }
626 ).finally(() => {

Callers 2

exportPromiseMethod · 0.95
readLoopMethod · 0.95

Calls 8

sendMethod · 0.95
releaseExportMethod · 0.95
abortMethod · 0.95
finallyMethod · 0.80
catchMethod · 0.80
thenMethod · 0.80
devaluateMethod · 0.80
resolveMethod · 0.45

Tested by

no test coverage detected