Repository navigation
isolate worker completions on dedicated gRPC connections - #166
Open
Tomer Rosenthal (torosent) wants to merge 7 commits into
Open
Tomer Rosenthal (torosent) wants to merge 7 commits into
Tomer Rosenthal (torosent) wants to merge 7 commits into
Conversation
A DTS server allows 100 concurrent streams per HTTP/2 connection, and the long-lived GetWorkItems stream holds one. With one connection per worker, completions and abandons for a busy worker queue behind that limit. Workers now keep one intake connection (Hello, GetWorkItems) and route an exact allowlist of Complete*/Abandon* methods round-robin over a bounded group of owned completion connections (default 3, 1-8 via WithWorkerCompletionConnections). Work is completed on the connection generation that accepted it, and a retired generation closes only after its in-flight work drains. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Tomer Rosenthal (torosent)
marked this pull request as ready for review
October 6, 2026 18:48
Copilot started reviewing on behalf of
Tomer Rosenthal (torosent)
October 6, 2026 18:49
View session
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Public documentation retains provisional internal-review language, and one factory validation error misidentifies intake failures.
Review effort: Balanced
Findings: 2
Open (2)
What changed in this PR
Introduces dedicated gRPC completion connections to prevent worker acknowledgements from competing with intake streams.
Changes:
- Adds configurable completion-connection groups with round-robin routing and generation-safe retirement.
- Preserves intake leases during graceful shutdown and cancellation.
- Adds extensive lifecycle, routing, ownership, and integration coverage.
| File | Description |
|---|---|
README.md |
Documents worker connection roles and budgets. |
CHANGELOG.md |
Records completion isolation and shutdown changes. |
client/grpc_worker.go |
Adds configuration and connection-group lifecycle. |
client/grpc_worker_compat.go |
Updates borrowed-listener requirements. |
client/grpc_worker_connection.go |
Implements completion routing and ownership. |
client/grpc_worker_connection_test.go |
Tests routing, limits, readiness, and cleanup. |
client/grpc_worker_drain_test.go |
Tests lease-preserving shutdown behavior. |
client/grpc_worker_processor.go |
Synchronizes dispatch and graceful draining. |
client/grpc_worker_transport_test.go |
Updates borrowed-transport coverage. |
durabletaskscheduler/README.md |
Documents completion isolation architecture. |
durabletaskscheduler/connection_test.go |
Tests compatibility-listener ownership. |
durabletaskscheduler/resource_id_test.go |
Updates authentication reconnect coverage. |
durabletaskscheduler/worker_completion_test.go |
Verifies owned connection option parity. |
exporthistory/versioning_test.go |
Supplies a dedicated test completion transport. |
samples/largepayloads/largepayloads_test.go |
Verifies intake remains leased through drain. |
samples/worker/README.md |
Documents the completion-budget sample. |
samples/worker/worker.go |
Demonstrates a one-connection completion budget. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Tomer Rosenthal (torosent)
October 6, 2026 19:08
View session
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Tomer Rosenthal (torosent)
October 6, 2026 19:24
View session
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Tomer Rosenthal (torosent)
October 6, 2026 19:37
View session
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Tomer Rosenthal (torosent)
October 6, 2026 19:51
View session
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Tomer Rosenthal (torosent)
October 6, 2026 20:17
View session
Contributor
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
The concurrency-sensitive connection ownership, reconnection, and lease-drain lifecycle warrants final human review despite comprehensive tests.
Review effort: Balanced
Findings: None
Resolved since last review (2)
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.


Why
A DTS server allows 100 concurrent HTTP/2 streams per connection, and a worker's long-lived
GetWorkItemsstream permanently occupies one. With a single connection per worker, activity/orchestration/entity completions and abandons queue behind that limit before they reach the server, so a busy worker stalls on acknowledgements even when its local concurrency limits have room.What
GetWorkItems, everything else) and routes an exact allowlist ofComplete*/Abandon*methods round-robin over a bounded group of dedicated completion connections. It is still one logical worker: oneWorkerID, one executor, one intake stream, and unchanged per-kind concurrency limits.WithWorkerCompletionConnections(n)(1–8, defaultDefaultWorkerCompletionConnections= 3; the default is a starting point, not a tuned optimum).Validation
go build ./...,go vet,gofmt, full tests and race checks pass, including minimum Go 1.25. CI passes on Go 1.25 coverage, Go 1.27 race, samples and CodeQL.615abb6versus1d83a1f: two 600-second windows at 1,075 starts/s, with the same Go 1.25 build, fixture, observers, resources and completion budget 3. The fixed worker acknowledged and client-validated all 645,000 planned workflows; SQL independently confirmed every output with zero unfinished instances. It measured 210,208 persisted actions/s during input, and 216,057 including drain. The pre-review control measured 196,006 during input and reached 94.7% of planned starts.Risk / reviewer notes