Skip to content

test: close statically proven CI race causes - #649

Merged
SunSi12138 merged 3 commits into
devfrom
fix/387-static-root-causes
Sep 10, 2026
Merged

SunSi12138 merged 3 commits into
devfrom
fix/387-static-root-causes

Conversation

@SunSi12138

@SunSi12138 SunSi12138 commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Refs #387.

Scope

This PR groups only root causes that can be closed from the current source/CI evidence. Each root cause is kept in a separate commit; no timeout widening, blanket retries, quarantine, or production behavior changes are used as a substitute for causality.

1. Tracked unary deadline at emission

SharpLinkClientTrackedEmissionDeadlineTests.TimedUnaryDroppedAtEmissionShouldCompleteWithoutDeadlineTimerCallback advanced manual time immediately after starting InvokeUnaryAsync, then used a later send-queue flush as if it proved the target Request had reached emission. There is no ordering edge between invocation scheduling and that flush marker, so the marker can complete first; because the test intentionally does not run deadline timers, the invocation can then remain pending until the test watchdog.

The test now uses the existing TestTransportConnection.RunOnNextOutputBufferRequest seam. Before arming the one-shot hook, it drains output already associated with ConnectAsync through the ready session's semantic FlushSendQueueAsync barrier, matching the established #392 pattern and excluding the initial heartbeat Ping from consuming the hook. Manual time therefore advances only when the send pump has actually reached the target Unary Request's output-buffer acquisition, immediately before the production emission path re-samples the deadline. This preserves the assertion that the expired Request never reaches transport without adding a wall-clock timeout or retry.

2. Protocol phase gate flush scheduler bound

NegotiatedSessionOptionsTests.SendPumpShouldEnforceProtocolPhaseBeforeQueueing had already completed the phase-rejection checks and queued the allowed draining Response, then wrapped the semantic FlushSendQueueAsync barrier in an unrelated two-second wall-clock WaitAsync.

The flush itself is retained because the final queue-accounting assertion requires the allowed cleanup frame to drain. Only the local two-second scheduler clock is removed.

Static-audit rule

The remaining #387 records were rechecked against current dev; a production-path fix is included only when state/ownership/protocol behavior can be proven wrong from the source. Historical items already closed by merged PRs are not duplicated, and unresolved one-off evidence is not changed speculatively.

Review follow-up

  • 2be9488d: establish a deterministic pre-existing-output barrier before the tracked-unary emission hook, so the first heartbeat Ping cannot consume the callback.
  • Inline review thread resolved after applying the fix.

Validation

CI is running on exact head 2be9488d386fa31d01ee3306dabd77e13205e78c.

@SunSi12138
SunSi12138 marked this pull request as ready for review September 10, 2026 10:34

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

整体两个 root-cause 方向都合理,第二个 phase-gate flush scheduler-bound 修复也有 #387 的 exact-head recurrence 证据。当前唯一 blocker 是 tracked-unary 新 hook 仍可能被 ConnectAsync 后立即启动的首个 heartbeat Ping 抢走,因此目标 Request 的 emission ordering edge 还没有完全建立,见 inline。

@SunSi12138
SunSi12138 marked this pull request as draft September 10, 2026 10:35
@SunSi12138
SunSi12138 marked this pull request as ready for review September 10, 2026 12:36

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

上次唯一 blocker 已修复:tracked-unary 测试现在先通过 ready session 的 FlushSendQueueAsync 排空 ConnectAsync/首个 heartbeat Ping 的既有输出,再 arm one-shot output-buffer hook,因此 callback 才真正唯一绑定到目标 Unary 的 emission boundary。第二处 phase-gate flush 改动仍只移除语义 barrier 外层的 scheduler-bound timeout。exact-head Fast / Extended / CodeQL 均通过,未发现新的工程级问题。

@SunSi12138
SunSi12138 merged commit 911bb34 into dev Sep 10, 2026
23 of 25 checks passed
@SunSi12138
SunSi12138 deleted the fix/387-static-root-causes branch September 10, 2026 13:05
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