Skip to content

[Bridge] Served ExecuteSyncNexusOperation in the frontend. - #66

Draft
moetemp wants to merge 7 commits into
moe/bridge/v2/u5h-notifier-to-standalonefrom
moe/bridge/v2/dr11-execute-sync-nexus-operation
Draft

moetemp wants to merge 7 commits into
moe/bridge/v2/u5h-notifier-to-standalonefrom
moe/bridge/v2/dr11-execute-sync-nexus-operation

Conversation

@moetemp

@moetemp moetemp commented Oct 14, 2026

Copy link
Copy Markdown
Owner

What changed?

This PR serves ExecuteSyncNexusOperation in the frontend.

  • The handler is in service/frontend/nexus_sync.go. It's off by default behind frontend.enableExecuteSyncNexusOperation, a namespace setting. Off answers Unimplemented.
  • The gRPC interceptors authorize the call on the caller namespace and count it against the caller's rate limit, as for any WorkflowService call. metadata.go has it as namespace scope with write access, and quotas.go has it at priority 1 beside StartNexusOperationExecution.
  • The request goes through the standalone validator parts, from the new nexusoperation.ValidateAndNormalizeSyncRequest.
  • The endpoint comes from EndpointRegistry.GetByName with the caller namespace ID, the seam that the other paths use for the allowlist. Only worker targets work.
  • The target namespace pays for the call with the DispatchByEndpoint API name, as on the HTTP route. A target that isn't active in this cluster answers NamespaceNotActive.
  • The frontend dispatches the task to matching with the deadline of the call, capped at nexusoperation.request.timeout. It answers the result or the failure. An async answer gives FailedPrecondition, and no answer gives DeadlineExceeded.
  • The redirection interceptor treats the RPC as local, since the caller namespace can be active in a different cluster than the target.
  • go.mod moves to the api-go of dr10.

Why?

A Bridge reader that opts in to direct reads calls the owner's stream service from a Local Activity and on replay (DD-153, DD-154 in the direct reads design). This RPC does that with the caller's own credential and the endpoint allowlist, and it leaves no state (DD-163). A standalone operation per read would keep each result and make each read an execution.

Please note that a handler that answers async has started its operation before the frontend refuses the answer. The stream service answers only sync, so this does not happen on the read path.

How did you test it?

Link to a test plan if any -

  • Unit Tests
  • Staging
  • End to End Tests

Unit tests in service/frontend/nexus_sync_test.go for each outcome, and for input above the blob size limit. Functional tests in tests/nexus_sync_test.go for a sync result across two namespaces, a handler error, an operation failure, an async answer, an unknown endpoint, no poller, the setting off, an authorizer that sees only the caller namespace, a denied caller namespace, and the caller and target rate limits. The Nexus and stream functional suites pass.

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