Skip to content

refactor(server): extract admission state kernel lifecycle - #328

Merged
SunSi12138 merged 219 commits into
devfrom
issue-324-admission-state-kernel
Aug 26, 2026
Merged

SunSi12138 merged 219 commits into
devfrom
issue-324-admission-state-kernel

Conversation

@SunSi12138

@SunSi12138 SunSi12138 commented Aug 24, 2026 •

Copy link
Copy Markdown
Owner

Implements #324 as the next stack slice above #323.

Stack base: reviewed #323 exact head 0711faa11500b22f08efb9a5225b53bd008ac479 (issue-322-admission-program-generation).

Scope

Limited to the #324 implementation manual:

  • stable server-scoped AdmissionStateKernel ownership for mutable Admission state/lifecycle;
  • safe current -> retired -> reclaimed AdmissionProgram lifecycle;
  • lock-free stale-read capture retry / retire-use CAS;
  • compatible Global / Contract / Method / rate / partition state reuse;
  • server-wide queue count/byte and active-permit accounting across generation overlap;
  • bounded program/state reclamation;
  • shutdown publication sealing, queued-work cancellation, and exact-once drain/disposal integration;
  • deterministic lifecycle/state/race coverage and feat(server): capture admission program generation per request #323 regression preservation.

Out of scope remains out of scope: no public runtime Admission mutation API, numeric limiter resize, dynamic queue policy changes, rate migration/algorithm replacement, partition selector/config migration, ServerResourceGovernor changes, decode/fair-scheduler changes, or connection-admission dynamic configuration.

Review follow-up

Addressed both reclamation/lifecycle review findings in 21a3ebef8e05b97dffd49cc13c5cf1209153d657:

  • final program-drain completion is now published only after detached limiter/partition state is physically disposed, controller state is detached, and the program transitions from reclaim-in-progress to reclaimed;
  • IsReclaimed / ReclaimCount no longer publish completion before state disposal;
  • deterministic KernelDisposeShouldWaitUntilFinalReclaimedStateIsDisposed blocks final state disposal and proves kernel DisposeAsync cannot return early;
  • reclamation severs the long-lived initial controller's references to its program and rule/partition state graph;
  • deterministic ReclaimedInitialControllerOwnerShouldNotRootOldProgramOrState keeps the lifecycle owner, kernel, and incompatible replacement alive while WeakReferences prove the reclaimed initial program and limiter state are collectable.

Exact-head validation

Exact PR head: 21a3ebef8e05b97dffd49cc13c5cf1209153d657

PR Quick: https://github.com/SunSi12138/SharpLink/actions/runs/32682326498 — PASS

  • Formatting: pass
  • Debug build: pass, 0 warnings / 0 errors
  • Release build: pass, 0 warnings / 0 errors
  • Generated assembly Runtime-reference verification: pass
  • Unit: 1124 / 1124 passed, 0 failed, 0 skipped
  • Generator: 134 / 134 passed, 0 failed, 0 skipped
  • Load Test Tests: 60 / 60 passed, 0 failed, 0 skipped
  • Integration: 385 / 385 passed, 0 failed, 0 skipped
  • NativeAOT transport/topology smoke: TCP + shared-memory/pre-credit pass
  • Pack/package verification: 7 package + symbol pairs verified; SDK generator, Hosting direct Runtime dependency, Abstractions no-DI dependency, and package reference-rooting checks pass
  • Load smoke (shared memory): c=1 133398 ok / 0 fail at 26678.51 qps; c=4 524351 ok / 0 fail at 104863.12 qps; 0.00% errors
  • Chaos smoke (120s, shared memory, c=16): success=777916, injected=168104, unexpected=0, restarts=11, clientErrors=0, serverErrors=0, unobserved=0; retained diagnostic 1490984 -> 1053888 (-29.32%)
  • Chaos artifact: chaos-pr-smoke, artifact ID 9504597103, SHA-256 d6961d0bb6553fa699f5fd1a695145ad5ba001d76c79030d81ac7489f2b974ee

#324 lifecycle / reclamation diagnostics

Deterministic tests prove the issue matrix rather than relying on timing-luck stress:

  • stale publication read cannot attach a post-retire use to N; capture retries N+1 and N reclaims exactly once;
  • a use acquired before retire remains valid, while retirement blocks every new use; last release triggers exact-once reclamation;
  • disabled capture performs 4096 captures with 0 allocated bytes and leaves live/retired program, rule/partition, queue, and permit state at zero;
  • identical Global/Contract/Method definitions reuse the same underlying state; an N permit constrains compatible N+1;
  • compatible rate publication retains consumed quota rather than creating a fresh limiter;
  • compatible partition publication reuses the same namespace/pool and active partition state;
  • overlapping N/N+1 generations share one queued-call bound and one queued-byte bound; retained bytes and active permits drain to zero;
  • captured QueueOneWayCalls policy remains per-Request across compatible publication;
  • 64 repeated compatible publication cycles keep LiveProgramCount=1, RetiredProgramCount=0, RuleStateCount=1 during steady state and finish with all three at zero;
  • incompatible state is retained only while the retired generation still has a use, then its registry entry is physically disposed and reclaimed; final replacement retirement returns rule-state count to zero;
  • final program-drain/reclaim completion is not observable until detached state disposal completes;
  • the server's retained lifecycle controller no longer roots a reclaimed initial generation/state graph;
  • Stop-vs-capture, Stop-vs-publication, queued-old-generation, and active-retired-generation tests all finish with queued calls/bytes, active permits, live/retired programs, rule state, and partition state at zero, with no ObjectDisposedException from old work.

The prior #323 DynamicAdmissionGeneration suite remains green, including controlled rejection/connection-reuse paths and retained-request budget cleanup. ServerResourceGovernor ownership remains independent and unchanged by this slice.

Both review threads have been addressed and resolved. PR is Ready for Review and remains stacked on #323. No merge or auto-merge has been performed.

Refs #324, #264, #273, #323, #319.

@SunSi12138
SunSi12138 marked this pull request as ready for review August 24, 2026 02:20

@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.

Follow-up review on exact head 21a3ebef8e05b97dffd49cc13c5cf1209153d657: both prior P2 findings are cleanly addressed. Final program-drain completion now follows physical state disposal + controller detach + reclaim completion, and the deterministic disposal barrier proves kernel Dispose cannot return early. Reclamation also severs the long-lived initial lifecycle controller's program/rule/partition references, with a WeakReference regression proving the old program/state graph is collectable while the lifecycle owner/kernel/replacement remain alive. I re-audited the detach path against request generation-use/lease ordering, subsequent candidate creation, and Stop/Dispose; no new P1/P2 found. Exact-head PR Quick 32682326498 is green. #328 can close for the #324 lifecycle/state-kernel slice.

SunSi12138 added a commit that referenced this pull request Aug 25, 2026
Base automatically changed from issue-322-admission-program-generation to dev August 26, 2026 17:36
@SunSi12138
SunSi12138 merged commit d4745ef into dev Aug 26, 2026
25 checks passed
@SunSi12138
SunSi12138 deleted the issue-324-admission-state-kernel branch August 26, 2026 18:14
SunSi12138 added a commit that referenced this pull request Aug 26, 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