Skip to content

test(testing): surface manifest-fetch diagnostics on convergence timeout - #11438

Merged
ReubenBond merged 5 commits into
dotnet:mainfrom
ReubenBond:rb-issue-11434-cosmos-reminder-manifest-con
Oct 9, 2026
Merged

ReubenBond merged 5 commits into
dotnet:mainfrom
ReubenBond:rb-issue-11434-cosmos-reminder-manifest-con

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Problem

Cosmos reminder scale-out intermittently exceeded the ten-second cluster-manifest convergence budget in #11434. The failing revision already included #11029, #11082, #11406, and #11116. The retained artifact recorded a GetSiloManifestHash request exceeding the thirty-second system RPC deadline, leaving the stalled observer's fetch and publication state to be determined.

Merged #11447 repairs a related transport publication race by completing both silo preambles before publishing the connection. Its deterministic regressions reproduce the ordering defect in both directions and its investigation addresses #11446 and #11434. The historical logs establish a common transport-failure signature; attribution of this specific recurrence remains subject to recurrence validation. This PR supplies durable observability for that validation and future recurrences.

Solution

Track internal per-attempt diagnostics in ClusterManifestProvider: membership version, start time, outstanding peer fetches, and the latest fetch failure. Each completion carries its originating attempt identity. Compare-and-swap updates preserve concurrent completions and carry forward failures recorded while the next attempt is installed. Cancellation is classified using the request token; independent peer cancellation is recorded and logged as a fetch failure.

Include each observer's manifest and attempt diagnostics in InProcTestCluster.WaitForTopologyToConvergeAsync timeout messages. Validate that the diagnostic reference remains stable across the manifest read, retrying when a completion or new attempt changes it. The returned values coexisted during the read. Their versions identify the published membership and the reconciliation attempt separately, including membership synchronized before the next attempt starts. Elapsed time uses the observer's own TimeProvider.

Cover the initial snapshot, successful completion, pending-set transitions, failures, stale completions, attempt-installation races, snapshot consistency, membership synchronization, cancellation classification, and exact timeout formatting with focused regressions.

Rationale

These internal diagnostics expose the stalled retrieval boundary while preserving topology convergence, provider validation, RPC deadlines, and retry behavior. They implement the issue's diagnostic outcome and complement the transport publication repair in #11447.

Improves diagnosability for #11434, which remains open for recurrence validation.

Copilot AI balanced review requested due to automatic review settings October 8, 2026 08:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Concurrent updates can produce stale or internally inconsistent diagnostic snapshots, and the timeout path lacks coverage.

3 open findings
What changed in this PR

Adds manifest-fetch diagnostics to topology convergence timeout failures.

Changes:

  • Tracks pending fetches, attempt timing, membership version, and failures.
  • Includes per-silo diagnostics in timeout exceptions.
File Description
src/​Orleans.Runtime/​Manifest/​ClusterManifestProvider.cs Captures manifest-update attempt diagnostics.
src/​Orleans.TestingHost/​InProcTestCluster.cs Reports diagnostics on convergence timeout.

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

Comment thread src/Orleans.Runtime/Manifest/ClusterManifestProvider.cs
Comment thread src/Orleans.TestingHost/InProcTestCluster.cs Outdated
Comment thread src/Orleans.TestingHost/InProcTestCluster.cs
Copilot AI balanced review requested due to automatic review settings October 8, 2026 08:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Concurrent updates can mix diagnostics from different manifest attempts and produce inaccurate timeout output.

3 open findings

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Code coverage

Metric Pull request Current main Variance
Lines 83.41% (118,411 / 141,956) 83.37% (118,281 / 141,879) +0.0464 pp
Branches 72.95% (35,175 / 48,220) 72.91% (35,139 / 48,194) +0.0353 pp

Report-only conclusion: improved.

The current-main baseline is commit 48f3aaa47f and uses the same reviewed coverage matrix.

Coverage combines every CI test matrix job, including providers, CodeGen, .NET 8/10, Linux, Windows, and macOS, using canonical physical source and branch identities.

The comparison remains report-only while normal line and branch variance is calibrated.

Coverage details

Tester.Cosmos.Reminders.ReminderTests_Cosmos intermittently times out
with 'Cluster manifests did not converge within 00:00:10' (dotnet#11434).
CI-artifact analysis of a failing run traced this to a silo whose
GetSiloManifestHash RPC to a peer sat unprocessed for ~30s (the
default system RPC response timeout) before replying, even though
the handler is a synchronous, in-memory hash computation with no
I/O. That is consistent with scheduling/thread-pool contention in
the shared single-process InProcessTestCluster rather than a logic
defect in the manifest fetch/retry/peer-repair paths, all of which
already include the fixes from dotnet#11029, dotnet#11082, and dotnet#11406.

Per the issue's accepted resolution, add diagnostics-only
instrumentation (no behavioral change) so a recurrence is directly
diagnosable from the failure message instead of requiring manual
CI-artifact archaeology:

- ClusterManifestProvider now tracks a per-attempt snapshot
  (membership version, attempt start time, silos still pending a
  manifest fetch, and the most recent fetch failure) and updates it
  as each individual fetch completes or fails, so pending silos
  shrink in real time rather than only being know at attempt start.
- InProcTestCluster.WaitForTopologyToConvergeAsync resolves the
  concrete internal ClusterManifestProvider and, on a convergence
  timeout, appends per-observer pending-fetch diagnostics to the
  thrown TimeoutException, taken from a single snapshot per observer
  (manifest + diagnostics + the observer's own TimeProvider) so the
  reported state is self-consistent even under a virtualized clock.

All new/changed members are internal; IClusterManifestProvider and
other public API are untouched, so no src/api regeneration is
required.
Adds focused tests for the new ManifestUpdateAttemptDiagnostics contract:
- LastAttemptDiagnostics is null before the first update attempt
- PendingSilos is fully cleared once all fetches in an attempt succeed
- PendingSilos shrinks per-fetch-completion in real time (not only after
  the whole attempt completes), and failure fields (LastFailedSilo,
  LastFailureMessage, LastFailureAt) are populated when a peer fetch fails

These exercise the new diagnostic output/state-transition contract itself,
complementing the pre-existing manifest-fetch success-path coverage.
- Bind MarkManifestFetchComplete to the attempt that started the fetch via a new AttemptId, preventing a stale direct-fetch completion from corrupting a newer attempt's diagnostics after peer repair.
- Add GetManifestAndDiagnosticsSnapshot() to pair LastAttemptDiagnostics with Current using a consistent read order, avoiding self-contradictory convergence-timeout messages.
- Make DescribePendingFetch internal and add direct formatter tests.
- Add a regression test proving a superseded attempt's completion is ignored.
Copilot AI balanced review requested due to automatic review settings October 8, 2026 21:21
@ReubenBond
ReubenBond force-pushed the rb-issue-11434-cosmos-reminder-manifest-con branch from e97e4a3 to 111b01a Compare October 8, 2026 21:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Snapshot and attempt-publication races can produce inconsistent or lost diagnostics, while unrelated cancellation failures are suppressed.

3 open findings
3 resolved since last review

🧠 Review effort: Balanced

Comment thread src/Orleans.Runtime/Manifest/ClusterManifestProvider.cs
Comment thread src/Orleans.Runtime/Manifest/ClusterManifestProvider.cs
Comment thread src/Orleans.Runtime/Manifest/ClusterManifestProvider.cs Outdated
- Format elapsed seconds in DescribePendingFetch using invariant culture so the diagnostic message (and its test) is not locale-dependent.
- Correct XML docs on GetManifestAndDiagnosticsSnapshot to accurately describe it as a best-effort pairing rather than an unconditional atomicity guarantee: a fetch completion or peer-repair publication between the two reads can still report a silo as both pending and already published.
Copilot AI balanced review requested due to automatic review settings October 8, 2026 21:28
@ReubenBond

Copy link
Copy Markdown
Member Author

Rebased on main to pick up #11447 (merged), which identifies and fixes the likely root cause of this flake: a premature-connection-publication race in SiloConnection/ConnectionManager (its own description states it "Addresses #11446 and #11434"). Updated this PR's description accordingly — it now adds durable observability rather than claiming to resolve root cause itself.

Also ran a rubber-duck self-review (gpt-6.1-sol) against the 3 code-review fixes and addressed both findings it raised:

  • DescribePendingFetch's elapsed-seconds formatting now uses invariant culture (was previously locale-dependent, which could also have made the new formatter test flaky on non-US-locale CI runners).
  • Corrected GetManifestAndDiagnosticsSnapshot's XML docs, which overstated the consistency guarantee: a fetch completion or peer-repair publication between the diagnostics read and the manifest read can still report a silo as both pending and already published. The method remains useful as a best-effort pairing for diagnostics; the docs now say so accurately instead of claiming an absolute guarantee.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Manifest and diagnostic reads remain non-atomic and can produce incorrectly paired timeout evidence.

3 open findings
Previously missed (1)

In code that hasn't changed since last review

Medium severity Ensure manifest and diagnostics are read from a consistent snapshot

src/​Orleans.Runtime/​Manifest/​ClusterManifestProvider.cs:108

This still does not produce the pairing promised by the method. Current can itself publish a newer partial manifest in EnsureValidManifestForCurrentMembership, so these exact two lines can read diagnostics for membership vN and then return a manifest at vN+1; a concurrent attempt can likewise install new diagnostics and publish before the second read. Reversing the reads only changes which inconsistent pairing is possible. The manifest and attempt diagnostics need a shared atomic/synchronized snapshot (or an equivalent consistency protocol) before this timeout output can reliably attribute pending fetches to the observed manifest.

🧠 Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 8, 2026 22:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The diagnostic state is concurrency-safe, does not alter convergence semantics, and has comprehensive focused coverage.

0 open findings

3 resolved since last review

🧠 Review effort: Balanced

@ReubenBond
ReubenBond merged commit b98141c into dotnet:main Oct 9, 2026
92 checks passed
@ReubenBond
ReubenBond deleted the rb-issue-11434-cosmos-reminder-manifest-con branch October 9, 2026 17:46
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.

2 participants