Skip to content

test(client): stabilize ready reconciliation observation - #615

Merged
SunSi12138 merged 1 commit into
devfrom
fix/issue-387-ready-reconciliation-followup
Sep 8, 2026
Merged

SunSi12138 merged 1 commit into
devfrom
fix/issue-387-ready-reconciliation-followup

Conversation

@SunSi12138

@SunSi12138 SunSi12138 commented Sep 8, 2026 •

Copy link
Copy Markdown
Owner

Refs #387

Scope

Test-only follow-up for the remaining recurrent #387 record:

SharpLinkReconnectPolicyLifecycleRaceTests.FailedReadyPublicationShouldNotStartDynamicStableResetWindow

Observed again on #608 PR Fast #1337 / run 34253679133 after #604. The failure was the exact-count assertion immediately after the third candidate became observable as Ready.

Root cause

The test treated ReadyConnectionCount == 1 as proof that the third response-compression Ready-reconciliation hook had already executed.

Production ordering is intentionally different: ConnectOneAsync adds the candidate and publishes the Ready snapshot first, then invokes ReconcileResponseCompressionPreferenceAfterReadyPublication. If that hook throws, the candidate is removed and the Ready snapshot is rolled back. Therefore a test observer may legally see ReadyConnectionCount == 1 in the interval after Ready publication but before the third hook invocation increments reconciliationAttempt.

That makes the immediate reconciliationAttempt == 3 assertion scheduler-sensitive even though reconnect ownership and Ready rollback behavior are correct.

Fix

Add one test-local TaskCompletionSource completed by the first non-throwing reconciliation-hook entry. After the direct transport ConnectAsync entry barrier for reconnect #3, await that hook-entry signal before checking Ready and retaining the exact reconciliationAttempt == 3 assertion.

This preserves the intended lifecycle contract:

  • the first two Ready publications still deterministically throw and roll back;
  • reconnect perf: recover v0.7.2 unary throughput and allocations #3 must still enter through the direct transport signal;
  • the successful third hook must actually execute;
  • Ready must still converge to 1;
  • the exact attempt count remains == 3, so duplicate reconciliation is not hidden;
  • the downstream five-second stable-reset-window assertions are unchanged.

Diff

Restacked base: dev@042c63bd036bdab38b2202eda096e6d59dfb3e0c (merged #613)
Head: 81290febf0749d712411bc38300d7164e18bc8dc

1 commit / 1 test file / +4/-0.

No production, workflow, timeout-widening, retry, quarantine, sleep, or polling changes.

Validation history

The first #615 run started against pre-#613 dev@f265492f... and its only Unit Test failure was FixedReconnectSuccessShouldResetTheNextFailureSequenceAfterPolicyUpdate, the separate flake fixed by #613. #613 merged while that run was already executing, so the branch was cleanly restacked afterward rather than mixing #613 into this PR's diff.

Final-head validation is from the post-restack CI only.

No local .NET SDK execution is available; validation is delegated to normal PR CI.

Copy link
Copy Markdown
Owner Author

CI attribution for review: final head 81290febf0749d712411bc38300d7164e18bc8dc passed CodeQL #3658. PR Fast #1350 reached 1583/1584 Unit Tests; its only failure was SharpLinkHealthCheckTests.LocalHealthCheckShouldNotAllocateACompletedTaskPerPoll, a separate #387 record now isolated in Draft #616. The #615 target FailedReadyPublicationShouldNotStartDynamicStableResetWindow passed on this final head. No #616 change is included here.

@SunSi12138
SunSi12138 marked this pull request as ready for review September 8, 2026 23:46
@SunSi12138
SunSi12138 merged commit b02bffe into dev Sep 8, 2026
24 of 27 checks passed
@SunSi12138
SunSi12138 deleted the fix/issue-387-ready-reconciliation-followup branch September 8, 2026 23:52
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