Skip to content

Pump-hosted QfcItemController tests expire at the 60s PumpTimeoutMs under CPU contention (real cause behind #511/#571) #592

Description

@drmoisan

Summary

The pump-hosted QfcItemController tests in QuickFiler.Test intermittently fail by expiring at the 60,000 ms PumpTimeoutMs when the machine is under CPU contention. This is the real defect behind #511 and #571, both of which attribute the failure to a missing window handle. That attribution is falsified — see the premise-correction comments on #511 and #571.

Evidence

Measured during the quickfiler-suite-determinism-foundation epic execution run on 2026-08-22. Full artifacts on branch bug/winformspumphost-suite-determinism-511-exec, commit 53a2a08f, under docs/features/active/winformspumphost-suite-determinism-511/evidence/.

  • The one genuine pre-fix failure was seven expiries at 60,000 ms, not an exception. A missing handle makes Control.Invoke throw immediately; it does not hang for sixty seconds.
  • Pre-fix run-level failure rate is about 1 in 21 (~4.8%).
  • Under induced 17-node MSBuild contention, a supplementary ten-run pass was 8 of 10 green. The failure reproduces under load.
  • Both WebView2 children, and therefore the parent ItemViewer, are already handle-created by InitializeComponent, so handle availability is not the variable.

Hypothesis to test (not a finding)

QuickFiler.Test/Controllers/QfcItemController.InitializationTests.Part2.cs defines a UiThreadDispatcherGate and a SwapUiThreadDispatcher helper that mutate the process-wide static UtilitiesCS.UiThread._dispatcher by reflection in order to serialize the pump tests across two test classes. QfcItemController.SeamFactoryTests and QfcItemController.InitializationTests contend on that gate.

A sixty-second expiry under CPU starvation is consistent with gate contention or a lock-ordering stall between those two classes, rather than with anything about window handles. That should be the first thing instrumented. It is stated here as a lead to test, not as a conclusion.

Also worth measuring: whether the pump thread is simply starved of CPU under contention, and whether any work currently performed on the pump thread can be moved off it.

Why this could not be fixed inside the originating epic

The quickfiler-suite-determinism-foundation epic forbade, by design, every remedy that plausibly addresses a load-induced timeout:

Those constraints were chosen against the misdiagnosed root cause. With the correct root cause, the constraint set leaves no in-scope remedy, which is why the epic child halted instead of shipping a no-op. Whoever picks this up should expect to re-open at least one of those constraints, and should decide deliberately which.

Acceptance Criteria

  • The mechanism producing the 60,000 ms expiry is identified and recorded with evidence, not inferred.
  • A regression test reproduces the failure deterministically, without a sleep, a retry, or a timing tolerance.
  • The fix is demonstrated effective against the reproduction, with a run count sufficient to distinguish it from the ~4.8% base rate (thirty clean runs alone is not sufficient; p ≈ 0.23 under the null).
  • Coverage of the two coverage-bearing files (QuickFiler/Controllers/QfcItemController.Initialization.cs, QuickFiler/Controllers/QfcItemController.ViewerSetup.cs) is retained or improved.
  • Bug: winformspumphost-tests-load-flaky-visible-window #511 and Bug: qfc-item-controller-init-tests-flaky-window-handle #571 are reconciled against the corrected root cause and closed or re-scoped explicitly.

Activity

  1. drmoisan commented on Sep 11, 2026

    @drmoisan
    OwnerAuthor

    Consolidated into #743 (2026-09-11)

    This issue and #743 describe the same defect: pump-hosted QfcItemController tests expire at the 60,000 ms PumpTimeoutMs bound under CPU contention. #743 carries the production-side direction (an injectable UI-marshalling seam in ItemViewer) that the #729 research concluded is the only deterministic remedy. The evidence-bar acceptance criteria from this issue have been copied onto #743 so they are not lost. Closing here; delivery is tracked on #743.

  2. drmoisan commented on Sep 11, 2026

    @drmoisan
    OwnerAuthor

    Consolidated into #743; see the comment above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions