Skip to content

STOR-5489: Measure Durable Object RPC replay memory - #7408

Open
apeacock1991 wants to merge 6 commits into
apeacock/jsrpc-call-observationfrom
apeacock/jsrpc-replay-memory-observation
Open

apeacock1991 wants to merge 6 commits into
apeacock/jsrpc-call-observationfrom
apeacock/jsrpc-replay-memory-observation

Conversation

@apeacock1991

@apeacock1991 apeacock1991 commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Depends on #7346.

Summary

  • Estimate replay retention for eligible direct Durable Object JSRPC calls.
  • Track one serialized-payload copy plus 1 KiB of call-plan state without retaining another copy.
  • Release accounting when the call settles, its caller context ends, or result-pipeline use commits to the current attempt.
  • Keep JavaScript-held tracking state in IoOwn so access and destruction stay on the originating IoContext.

This change measures projected retention only. It does not enable sender replay.

Actors built by TestFixture had no class, so any test that sent an
actor request through the real entrypoint failed with "Failed to get
handler to worker" before reaching user code. actorClassName names the
exported Durable Object class to construct on the first request.
JsRpcSessionCustomEvent::run() now calls
claimRetryTokenBeforeUserCode() before delivered(). A rejected claim
is passed to failed() so the session capability carries the rejection
details instead of a generic teardown disconnect.

Failures after delivery carry the worker-delivered and actor-delivered
details and drop the not-delivered marker. This covers method errors,
session failures, and actor aborts on the revocation path.
A replayable call to a destination that supports actor call retries is
dispatched through newActorCallAttempt() with a first-attempt token.
Property reads, transient stubs, and calls with non-replayable
arguments stay on the single-use path. The token has enforcement
disabled, and there is no replay loop yet.

Both ends are behind a new observe-only autogate,
DURABLE_OBJECT_RETRIES_JSRPC, so JSRPC can roll out separately from
the fully deployed fetch gates. A JSRPC retry-request gate will follow
with sender replay.

The gate-off sender tests initialize exactly the gates they name, with
IgnoreAllAutogatesEnv::YES, so they hold under the all-autogates test
variant.

The receiver tests assert claim and delivery details on the native
JsRpcTarget.call() result, and cover a rejected claim leaving the
actor unconstructed, getter failures, and a native not-delivered
disconnect that aborts the actor after the call was delivered.
RequestObserver::observeOutgoingActorRpcCall() returns an
OutgoingActorCallObserver for one JsRpcTarget.call() attempt. The
caller records success or failure from the call's own result. If the
observer is dropped first, that means the attempt was canceled.

ActorCallPayloadReplayable moves from actor-call-retry.h to observer.h
so the hook and ActorCallRetryState use the same type. Nothing calls
the hook yet.
Durable Object JS RPC calls were observed through their session
promise, which settles with capability lifetime rather than call
latency and does not describe the call payload.

Observe each call result instead. The outgoing provider reports
optional actor target retryability, distinguishing non-actor calls
from retryable and non-retryable actor calls. Fetch uses the same
classification, including colo-local actors and facets.

Calls through pending actor result pipelines retain actor provenance
but cannot create a fresh attempt independently. Tests cover this
path, payload replayability, settlement ordering, cancellation, and
target eligibility.
Track projected memory for replayable JSRPC calls without retaining
another payload copy.

Release accounting when the call settles, its caller context ends, or
pipeline use commits it to the current attempt.
@apeacock1991
apeacock1991 requested review from a team as code owners September 17, 2026 12:53
@ask-bonk

ask-bonk Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

LGTM

github run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant