Skip to content

feat(client): resize connection pools at runtime - #599

Merged
SunSi12138 merged 1 commit into
devfrom
issue-587-runtime-connection-pool-sizing
Sep 8, 2026
Merged

feat(client): resize connection pools at runtime#599
SunSi12138 merged 1 commit into
devfrom
issue-587-runtime-connection-pool-sizing

Conversation

@SunSi12138

@SunSi12138 SunSi12138 commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Closes #587

Runtime sizing surface

Adds one live connection-capacity generation over the existing fixed/static/dynamic Client lifecycle.

  • fixed topology atomically publishes {MinConnections, MaxConnections};
  • static/dynamic clusters atomically publish {MaxConnections, MaxConnectionsPerEndpoint} while leaving MinReadyEndpoints, endpoint membership, selection and resolver semantics unchanged;
  • the live options objects used by the existing connection/reconnect paths remain the authoritative capacity domain, so old/new limits cannot stack as independent pools;
  • invalid candidates are rejected before publication and Stop/drain/fault seals further updates.

Reconciliation semantics

  • fixed MinConnections growth reuses the existing reconnect/connection creation path;
  • cluster growth remains driven by existing min-ready/reconnect and pressure-expansion machinery under the newly published hard limits;
  • scale-down marks surplus Ready connections Draining before they disappear from new-attempt eligibility;
  • idle surplus retires immediately through the existing connection cleanup path;
  • active unary/streaming work is not cancelled for resize: active surplus stays connected until its active count reaches zero, then the existing idle-retirement path disposes it exactly once;
  • per-endpoint shrink groups by the existing endpoint identity + generation, and total shrink preserves the configured ready-endpoint threshold;
  • one supervised control-plane reconciliation task handles in-flight dials and repeated grow/shrink updates; ordinary RPC selection gets no new global lock or allocation.

Review follow-up: shared retirement budget

The review correctly identified that the earlier implementation only combined resize and normal retirement counts from the resize side. That left a race where a normal GoAway/topology retirement could reserve another active retirement after resize had sampled the count.

The follow-up removes the separate _resizeRetiringConnections accounting entirely. For an active resize candidate, the capacity check and the existing MarkConnectionDraining transition are now serialized under the cluster's own Lock. The transition therefore inserts the resize drain into the same static/dynamic retiring collection already used by normal GoAway/topology retirement. Both lifecycle sources now observe one authoritative active-retirement count, and an exhausted budget makes resize wait rather than force-close existing work.

A narrow control-plane accessor is still used to reach the private nested runtime gate/count without exposing new public/runtime surface; the unlocked read and second retiring-state domain that caused the concurrency bug are gone.

Regression coverage

SharpLinkClientRuntimeConnectionPoolSizingTests covers:

  • fixed Min growth converging from 1 -> 3 through the existing transport lifecycle;
  • fixed Max shrink with active work: surplus becomes Draining, remains connected, then closes after the call drains;
  • static cluster shrink with MaxRetiringConnections = 0: active surplus remains Ready/connected rather than being force-closed, then converges after active work drains;
  • StaticResizeReservationShouldBeVisibleToNormalRetirementBudget: resize first consumes the single active-retirement slot, then the normal cluster retirement entry point is exercised and must observe that reservation rather than creating a second active drain;
  • invalid candidate rollback and Stop publication sealing;
  • static and dynamic topology API/model separation and generation snapshots.

The branch was cleanly restacked onto current dev so exact-head hardening workflows contain their current #576/#571 test infrastructure while the PR diff remains limited to the five #587 files.

Branch head: 2de2e08692dd0f2557ef4f01fb1f0235a238ec33.
Validated target: dev@d3eab9e4b54da1d9e6984e15481d6fee714bfb70.

Validation

  • PR Fast 34196978321: PASS — formatting/maintainability, Release build, generated-assembly boundary, full Unit/Generator/Load suites, and deterministic allocation gate.
  • CodeQL 34196978288: PASS.
  • Pending and codec validation 34196978137: PASS.
  • Extension fault containment 34196978147: PASS.
  • PR Extended 34197193068: PASS — Debug/Release builds, Integration Tests, NativeAOT transport/topology smoke, package contract verification/smoke, demo/load smoke, and the complete six-platform desktop codec compatibility matrix.

@SunSi12138 SunSi12138 closed this Sep 8, 2026
@SunSi12138
SunSi12138 force-pushed the issue-587-runtime-connection-pool-sizing branch from 3ff2685 to 3bccdef Compare September 8, 2026 01:41
@SunSi12138 SunSi12138 reopened this Sep 8, 2026
@SunSi12138
SunSi12138 marked this pull request as ready for review September 8, 2026 05:58

@SunSi12138 SunSi12138 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One engineering-significant concurrency issue in the resize retirement-budget accounting; inline below. I otherwise did not find a reason to broaden the scope.

Comment thread src/SharpLink.Client/SharpLinkClient.RuntimeConnectionPoolSizing.cs Outdated
@SunSi12138
SunSi12138 force-pushed the issue-587-runtime-connection-pool-sizing branch from e2b09fa to 2de2e08 Compare September 8, 2026 06:57
@SunSi12138
SunSi12138 marked this pull request as draft September 8, 2026 06:59
@SunSi12138
SunSi12138 marked this pull request as ready for review September 8, 2026 06:59
@SunSi12138
SunSi12138 merged commit ba33213 into dev Sep 8, 2026
29 checks passed
@SunSi12138
SunSi12138 deleted the issue-587-runtime-connection-pool-sizing branch September 8, 2026 07:21
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