Skip to content

Pinned api-go to the branch carrying the stream protos. - #3

Closed
moetemp wants to merge 14 commits into
mainfrom
moe/AI-198-srv-1-api-pin
Closed

moetemp wants to merge 14 commits into
mainfrom
moe/AI-198-srv-1-api-pin

Conversation

@moetemp

@moetemp moetemp commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

This PR pins go.temporal.io/api to the api-go fork that carries the stream and notification channel protos.

What changed?

  • go.mod replaces go.temporal.io/api with github.com/moetemp/api-go at the head that carries the linked-channel contract. Nothing stream-specific runs on this layer. It moves the api and repairs what the move breaks.
  • The pin adds NotifyChannel, RegisterChannelListener, UnregisterChannelListener, PollChannel and DescribeChannel to WorkflowService. The generated frontend clients, the workflowservicemock mock and the log tags pick them up. Every per-method table gets its entries: common/api/metadata.go, the frontend and persistence quotas, redirection, the DC redirection policy and telemetry.
  • The WorkflowHandler stubs for the five channel calls answer Unimplemented. Added the notification channel: listeners woken on their scheduled task. #9 replaces the stubs with the real handlers.
  • service/history/historybuilder/event_store.go keeps the two stream command events and WorkflowNotificationChannelSubscribed out of the event buffer, like every other command-generated event. The history builder test walks every event type, so the pin alone fails it.
  • tests/api_fork_test.go round-trips the new command, poll-response and completed-event shapes over the wire. A field added without its descriptor compiles and then drops on marshal.
  • cmd/tools/getproto/files.go maps the stream and notification protos the pin ships.
  • common/metrics/otel_metrics_handler_test.go ignores the Exemplars field. The metric SDK returns nil or an empty slice, depending on whether it allocated the reservoir. The rest of the comparison stays strict.
  • In the Makefile, clean-test-output removes test.log, which verify-test-log reads whole. A failure left by an earlier run otherwise fails every later check. build-tests builds the tests/mixedbrain module from its own directory, since the root go test can't reach it.

Part of AI-198 (epic AI-37).

Why?

Every later layer depends on the new api. The pin and its fallout are easier to judge on their own than mixed into the stream code. The channel calls get stubs here because the frontend handler has to satisfy the pinned service interface, and the code that serves them belongs with the channel.

How did you test it?

go build ./... passes. make proto and make fmt leave the tree clean. I ran the meter tests in ./common/metrics/..., the history builder tests, and the frontend and interceptor tests. The functional test TestApiForkCarriesStreamShapes ran with -tags test_dep. The channel stubs have no test on this layer. The real RPCs and their tests land in #9.

  • Unit Tests
  • Staging
  • End to End Tests

The branch builds against the fork's api, which pulls newer gRPC and OpenTelemetry through the module graph and ships the nexusoperation and stream protos the import map has to list.
Taken from upstream temporalio/temporal temporalio#11906. The api version this branch pins rejects a system payload that is not binary/protobuf, so the endpoint has to refuse one instead of labelling it.
Equating empty across the whole comparison also hid a nil-versus-empty
attribute set or data point, which is not what the test is about.
The api branch renamed the two stream command fields and reshaped the appended event's range. The layers above this one need the new accessors.
The chain sat 130 commits behind main. Upstream's go.mod won and only the
api-go fork replace was re-applied on top, and upstream has since landed the
system Nexus protobuf payload check that this layer used to carry.
The re-pinned api-go names the appended stream by StreamName, so the pin test stops compiling without it.
The api pin adds two command types, and every command's event needs a
buffering decision or the history builder's classification check fails.
The command handling itself lands with the workflow commands layer.
The new RPC joins the generated clients and the per-method tables here, and the frontend answers it with Unimplemented until the delivery layer serves it.
The pin declares the five channel RPCs, so the frontend clients, mock and method tables list them, and the handlers answer Unimplemented until a later layer serves them.
The pin also carries the linked-channel contract (Notification.linked_to, ChannelKind, workflow_execution on the channel requests and the linked HTTP routes), which no layer of this series acts on yet. The frontend clients, the workflowservice mock and the logtags are regenerated from it.
…mand.

The pin carries ChannelSubscriptionInfo on DescribeWorkflowExecutionResponse and the UnsubscribeNotificationChannel command, event and failed cause, which later layers of this series act on. The history builder classifies the new event as one a command generates, so it is not buffered. No RPC changed, so the clients, the mock and the logtags regenerate to the same files.
The five channel requests and linked_to address an owner by Execution
rather than by WorkflowExecution. The logtags interceptor is regenerated.
The Execution fields reuse the numbers the workflow fields had, with
nothing reserved. Names and types are unchanged.
@moetemp

moetemp commented Oct 3, 2026

Copy link
Copy Markdown
Owner Author

Replaced by #18, #19, #20, #21, #22, #23, #24, #25, #26, #27, #28, #29, #30, #31, #32, #33, #34, #35, #36 and #37.

Same content, split into 20 PRs in the v3 series: the notification channel first, then the streaming interface, then native streams and the rest. The branch stays as a pin.

@moetemp moetemp closed this Oct 3, 2026
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