`exportStub()` always allocates a new export ID, even for duplicate capabilities

オープン
#141 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 5 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
typescript

調査の方向性

Trace exportStub() in src/rpc.ts and the devaluateHook, getHookForRpcTarget(), and getHookForWritableStream() paths in src/serialize.ts. Compare hook duplication with reverseExports and the intentional non-deduplication in exportPromise. Done should ensure repeated exportable capabilities can reuse export IDs without changing promise behavior or reintroducing the remoteRefcount issue in #140.

索引モデルが issue の本文から書いたものです。

説明

exportStub() deduplication by hook identity never fires.

https://github.com/cloudflare/capnweb/blob/c2bb17b940b23eb8ab89be1e85538493cb4552ad/src/rpc.ts#L369-L383

reverseExports is a Map<StubHook, ExportId>, so dedup is by object identity.

https://github.com/cloudflare/capnweb/blob/c2bb17b940b23eb8ab89be1e85538493cb4552ad/src/serialize.ts#L275-L281

devaluateHook routes to either exportStub or exportPromise depending on whether the type is "export"/"writable" or "promise". The promise path is intentionally never deduplicated (exportPromise comment: "Promises always use a new ID because otherwise the recipient could miss the resolution."), so the issue only concerns the paths that reach exportStub:

"stub"/"rpc-promise" https://github.com/cloudflare/capnweb/blob/c2bb17b940b23eb8ab89be1e85538493cb4552ad/src/serialize.ts#L218-L224 hook is set to the result of hook.dup() if pathIfPromise is falsy (the only time exportStub will be called).

"function"/"rpc-target" https://github.com/cloudflare/capnweb/blob/c2bb17b940b23eb8ab89be1e85538493cb4552ad/src/serialize.ts#L233-L234
getHookForRpcTarget() returns hook.dup() for "return" payloads (after correctly deduplicating in rpcTargets by target object identity), or a fresh TargetStubHook.create() each time for "params" payloads. Either way, a fresh object reaches exportStub.

"writable" https://github.com/cloudflare/capnweb/blob/c2bb17b940b23eb8ab89be1e85538493cb4552ad/src/serialize.ts#L251-L252
getHookForWritableStream() uses identical logic to getHookForRpcTarget() for our purposes, it deduplicates in rpcTargets for "return" payloads but returns hook.dup() each time, fresh WritableStreamStubHook each time for "params".

In all three cases, dup() always returns a new object for every hook type that can be exported (RpcImportHook, TargetStubHook, WritableStreamStubHook, ReadableStreamStubHook, PayloadStubHook). The two types where dup() returns this (ErrorStubHook and MapVariableHook) are never exported.

Because the stub fed to exportStub is always a newly created object, it will never be found in reverseExports, so we will always create a new export.

This means the same capability appearing twice always gets separate export IDs. This is what prevents the remoteRefcount bug (#140) from being triggered currently

主要言語
TypeScript
スター
4k
フォーク
150
平均マージ
3日 12時間
マージ済み PR(30日)
2

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

cloudflare/capnweb のほかの issue

cloudflare/capnweb の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。