Repository navigation
Go SDK: add the Join helper for parallel branches - #1553
Merged
Merged
Conversation
Join is a typed view over a ChannelMap of branch results. Fork keys each round by the split Step's execution ID and counts the branch builders; ForkWithRoundKey serves RPCs. Branches report with EndBranch or ReportBranchResult; the join waits with ForAllBranches, ForFirstBranch, or ForBranches; the next round resets with ForRemainingBranches. Adds the JoinRound JSON contract test and Join integration tests.
DefineJoin becomes a ChannelMap resource. Join wait conditions draw wait_condition edges with Join labels, EndBranch and ReportBranchResult draw publish edges, BranchResults and RemainingBranchResults draw read edges, and EndBranch is a Dead end decision. Fork and ForkWithRoundKey movements built by builder functions become fan-out transitions, also when an RPC returns them in NextSteps.
…celed-round resets
… Join test The contract test decodes a JoinRound with an unknown extra field. The canceled-branch test waits for the split before canceling, keeps the Flow open, and asserts that branch B's later release stays pending and that B reports no result.
Join.ChannelMap returns the registered same-name ChannelMap, so RPCs can read or load a round's pending results by its round key. Applications never publish to it. The integration tests read pending results through it, and the contract test checks that it is the registered ChannelMap.
The canceled branch marks itself waiting in its WaitFor commit, and the test polls that marker before canceling. Key isolation and partial rounds prove the join did not trigger through ordered RPC reads and the final Flow result instead of a two-second WaitForStepCompletion timeout.
Move the Join change log entry into the 1.43 section next to the existing Added entry, link it to the Go API reference, and change the Join version markers from 1.41.0 to 1.43.0.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This was referenced Nov 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the Join helper to the Go SDK: a join construct for parallel branches, built only on the existing ChannelMap. No server, IDL, or persistent-format change besides the
JoinRoundJSON value.Join[T](DefineJoin[T](name), a sealedChannelDeflisted inPersistenceSchema.Channels):Fork/ForkWithRoundKeystart the branches and the join Step with oneJoinRound; branches report withEndBranchorReportBranchResult; the join waits withForAllBranches,ForFirstBranch, orForBranches; the next round resets withForRemainingBranches; results are read withBranchResults/RemainingBranchResults.JoinRound{RoundKey, BranchCount}, JSON{"roundKey","branchCount"}pinned byTestJoinRoundJSONContract.ForkWithRoundKeytakes an explicit key (for RPCs). Forking the same Join twice in one invocation fails;Forkworks only in Execute. Invalid counts fail the WaitFor with explicit errors;ForFirstBranchon a zero-branch round fails (shared rule for all five SDKs).receivedCountcounts only what the join consumed; a cancelling join's round is fully reset only if an RPC reports the cancelled branches; RPC forks useCancelSteps. "Since 1.41.0." Channel and ChannelMap docs point to Join.sdk-go/README.mdgains "Joining parallel branches";docs/design/plan/go-sdk-rewrite.mdlists the API.DefineJoinis a map channel resource; theFor*conditions are wait edges,EndBranch/ReportBranchResultpublish edges, the result reads read edges, andForkbuilders become fan-out edges (×N for builders appended in a loop), with a fixture test.docs/reference/go/changelog.mdx(1.41) andsdk-go/CHANGELOG.md.Why
The owner approved the Join helper design (decisions D1-D6, 2026-11-10). Without it, an application implementing a join counts branches and round keys itself, so 14 Workflow Patterns are rated
+/-; with a documented construct in all five SDKs they become+. This is the Go part; Java is #1549, Rust #1550, TypeScript #1552, Python follows. Examples migrate after the SDK release becauseexamples/gopins the released SDK.doc-map: no change needed: SDK API, analyzer, and reference changelog only; docs, skills, and examples change after all five SDKs ship
Testing
sdk-go/integ/join_test.go: every scenario in the design's test table, including a gate Step proving results were committed before the join waited, an RPC read of the pending late result after sibling cancellation, and server acceptance ofForN(key, 0);^TestJoinpassed 3 runs in a row; the fullrun-e2e-tests.shpasses.go test ./dex,make docsCheck,go vet,make copyright-check; cliGOWORK=off go test ./...and-tags=integration ./internal/command -run 'TestVisualize|TestWeb';npm run generate:flow-definitionsshows no drift;cd docs && npm run check.