Skip to content

Pandas Explorer wait FOLLOWS the overlay's redirect instead of dying on it (#2155) - #2280

Merged
rbuergi merged 3 commits into
mainfrom
fix/2155-pandas-explorer-follows-overlay-redirect
Aug 25, 2026
Merged

Pandas Explorer wait FOLLOWS the overlay's redirect instead of dying on it (#2155)#2280
rbuergi merged 3 commits into
mainfrom
fix/2155-pandas-explorer-follows-overlay-redirect

Conversation

@rbuergi

@rbuergi rbuergi commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Closes #2155.

PandasExplorerLayoutAreaTest.Explorer_NoPythonNode_RendersToolbarAndDegradesGridWithoutHanging
spends its whole 50 s budget on a RedirectControl and fails. Three occurrences in the last 300
MeshWeaver Build and Test runs (2026-08-24 14:18, 2026-08-25 09:43, 2026-08-25 18:32), each on a
branch whose diff cannot reach the Doc sample's layout composition.

What actually happens — and it is not a slow render

When the cold Roslyn compile of the Pandas NodeType outlives
NodeTypeEnrichmentHelpers.InFlightOverlayGrace (5 s — a loaded CI runner routinely does), the
LiveFrame instance activates against the compilation-in-progress overlay, which serves
NodeTypeLayoutAreas.CompileProgressView on EVERY area. When the build lands Ok that view emits
a RedirectControl — and the same event recycles the instance hub: WithOverlaySelfHeal posts
a DisposeRequest to it so the next access re-enriches against the now-usable type.

A subscriber that merely keeps waiting is therefore attached to a hub that has gone away. The
redirect is the last thing it ever sees, and the remaining ~45 s of the budget are spent on a dead
stream — exactly what the issue recorded:

Last of 3 emission(s) was: RedirectControl { …, Href = /Doc/DataMesh/PythonPandasNode/PandasExplorer/LiveFrame/Explorer }

Per no-band-aids: the bound is the detector, so this does not widen it. What was missing is that
the test never did what a client does with a redirect.

The fix — follow it, the way the client does

Blazor's DispatchView answers a RedirectControl with NavigationManager.NavigateTo(href), i.e.
a fresh area subscription. Every wait now goes through a Rendered(...) helper that, on a
RedirectControl, re-subscribes from a fresh client hub. A new client is this test's
navigation: its workspace opens a brand-new remote stream rather than handing back the orphaned one
out of Workspace._remoteStreamCache (keyed on owner + reference + identity, so re-asking the same
client would return the same dead stream).

No timer, no retry, no widened bound — the redirect IS the event, and each hop is driven by
receiving one. MaxRedirectHops bounds it so an instance stuck in an overlay↔heal loop still fails
inside the 50 s budget instead of spinning.

RED before / GREEN after — deterministic, no timing

InFlightOverlayGrace was temporarily set to 1 ms locally, which forces the overlay path CI only
reaches under load:

tree grace outcome
main 1 ms FAIL at 50 sLast of 6 emission(s) was: RedirectControl … Href = /Doc/.../LiveFrame/Explorer (the issue's text, verbatim)
this PR 1 ms PASS in 2 s, logging [Explorer] compile-progress overlay redirected to … — re-subscribing (2 hop(s) left)
this PR 5 s (shipped) PASS in 2 s — the fast path is untouched

The grace change was only a probe; it is not in this diff (git diff origin/main...HEAD --stat is
one file, the test).

Noted while investigating, NOT fixed here

The same shape is worth a look in production and is filed as a comment on #2155 rather than smuggled
in: the overlay's redirect href is the URL the user is already on, and LayoutAreaView is keyed
on the stream identity (Address, Reference) — which the redirect does not change — so
NavigateTo(sameUrl) need not remount it, and Workspace._remoteStreamCache would hand the
remounted view the same orphaned stream. That is a separate question from this flake and needs a
browser to settle.

What's New

Skipped: test-only change, no user-visible effect.

🤖 Generated with Claude Code

…on it (#2155)

`PandasExplorerLayoutAreaTest` failed on CI with 50 s spent on a
`RedirectControl`, three times in the last 300 runs. It is not a slow render
and it is not the branch under test.

When the cold Roslyn compile of the Pandas NodeType outlives
`NodeTypeEnrichmentHelpers.InFlightOverlayGrace` (5 s — a loaded CI runner
routinely does), the `LiveFrame` instance activates against the
compilation-in-progress overlay, which serves `CompileProgressView` on EVERY
area. When the build lands `Ok` that view emits a `RedirectControl` — and the
SAME event recycles the instance hub (`WithOverlaySelfHeal` posts a
`DisposeRequest` to it) so the next access re-enriches against the now-usable
type. A subscriber that merely keeps waiting is therefore attached to a hub
that has gone away: the redirect is the last thing it ever sees, and the
remaining 45 s of the budget are spent on a dead stream.

Following the redirect is what a real client does — Blazor's `DispatchView`
answers a `RedirectControl` with `NavigationManager.NavigateTo(href)`, i.e. a
fresh area subscription. Every wait now goes through `Rendered(...)`, which on
a `RedirectControl` re-subscribes from a FRESH client hub (a new client is this
test's navigation: its workspace opens a new remote stream instead of handing
back the orphaned one out of `Workspace._remoteStreamCache`, which is keyed on
owner + reference + identity). No timer, no retry, no widened bound: the
redirect IS the event, and the hop count is bounded so an instance stuck in an
overlay-heal loop still fails inside the 50 s budget.

RED before / GREEN after, deterministically: with `InFlightOverlayGrace`
temporarily set to 1 ms — which forces the overlay path that CI only reaches
under load — the old test fails at 50 s with the issue's exact text ("Last of 6
emission(s) was: RedirectControl … Href =
/Doc/DataMesh/PythonPandasNode/PandasExplorer/LiveFrame/Explorer") and the new
one passes in 2 s, logging the hop it followed. With the grace back at its
shipped 5 s the test passes in 2 s as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 25, 2026 21:14

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.

Pull request overview

This PR addresses CI flakes in PandasExplorerLayoutAreaTest.Explorer_NoPythonNode_RendersToolbarAndDegradesGridWithoutHanging by making the test’s reactive “wait until rendered” logic follow the compile-progress overlay’s RedirectControl (mirroring how the GUI navigates) instead of waiting on a stream that can go dead after the overlay self-heals and disposes the instance hub.

Changes:

  • Introduces a Rendered(...) helper that re-subscribes with a fresh client hub when a RedirectControl is observed (bounded by MaxRedirectHops).
  • Updates all waits in the test to use Rendered(...) rather than holding a single remote-stream subscription across overlay disposal.
  • Adds targeted documentation in the test explaining the overlay redirect + hub recycle behavior behind issue #2155.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread test/MeshWeaver.Hosting.Monolith.Test/PandasExplorerLayoutAreaTest.cs Outdated
…l names it

An `Observable.Empty` on the last hop completed the wait with no value, so a
genuine overlay↔heal loop would have reported "nothing arrived" instead of
"Last of N emission(s) was: RedirectControl … Href = …" — which is precisely
the line that made #2155 diagnosable. The redirect is now passed through: it
matches no caller predicate, so the wait still fails on its own budget, and the
report keeps naming what was actually last seen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

Test Results (shard 0)

1 201 tests  ±0   1 201 ✅ ±0   15m 28s ⏱️ - 1m 3s
    9 suites ±0       0 💤 ±0 
    9 files   ±0       0 ❌ ±0 

Results for commit db396ad. ± Comparison against base commit e6a1945.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

Test Results (shard 4)

2 106 tests  ±0   1 806 ✅ ±0   8m 36s ⏱️ +33s
    9 suites ±0     300 💤 ±0 
    9 files   ±0       0 ❌ ±0 

Results for commit db396ad. ± Comparison against base commit e6a1945.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

Test Results (shard 1)

1 880 tests  ±0   1 880 ✅ ±0   7m 20s ⏱️ -36s
   10 suites ±0       0 💤 ±0 
   10 files   ±0       0 ❌ ±0 

Results for commit db396ad. ± Comparison against base commit e6a1945.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

Test Results (shard 3)

    9 files  ±0      9 suites  ±0   5m 35s ⏱️ - 1m 3s
1 823 tests ±0  1 819 ✅ ±0  4 💤 ±0  0 ❌ ±0 
2 353 runs  ±0  2 349 ✅ ±0  4 💤 ±0  0 ❌ ±0 

Results for commit db396ad. ± Comparison against base commit e6a1945.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

Test Results (shard 5)

   10 files  ±0     10 suites  ±0   6m 48s ⏱️ -7s
1 301 tests ±0  1 300 ✅ ±0  1 💤 ±0  0 ❌ ±0 
1 302 runs  ±0  1 301 ✅ ±0  1 💤 ±0  0 ❌ ±0 

Results for commit db396ad. ± Comparison against base commit e6a1945.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

Test Results (shard 2)

3 305 tests  ±0   3 305 ✅ ±0   9m 59s ⏱️ +44s
    8 suites ±0       0 💤 ±0 
    8 files   ±0       0 ❌ ±0 

Results for commit db396ad. ± Comparison against base commit e6a1945.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

Test Results

    55 files  ±0      55 suites  ±0   53m 49s ⏱️ - 1m 31s
11 616 tests ±0  11 311 ✅ ±0  305 💤 ±0  0 ❌ ±0 
12 147 runs  ±0  11 842 ✅ ±0  305 💤 ±0  0 ❌ ±0 

Results for commit db396ad. ± Comparison against base commit e6a1945.

♻️ This comment has been updated with latest results.

@rbuergi

rbuergi commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

CI red on MeshWeaver.AI.Test.AiContentPackDriftTest.EveryFile_StillHashesToItsPinnedReconciliationPoint (run 32900892481, shard 3 — the only failing test).

Not this diff, and not re-runnable. This PR changes exactly one file, test/MeshWeaver.Hosting.Monolith.Test/PandasExplorerLayoutAreaTest.cs (git diff origin/main...HEAD --stat), which cannot reach a content-pack hash ledger. main is currently red on the same guard — a content edit landed without re-pinning its ledger — and the pin lives IN THE TREE, so every open PR carries it and a re-run re-samples the identical failure rather than a flake.

Waiting for the re-pin (#2288 / #2284) to land on main, then merging main here — one of the two cases AGENTS.md sanctions for merging main into a branch ("CI fails on something your diff does not touch"). Not merging this until its own required check is genuinely green.

@rbuergi
rbuergi merged commit 51b306d into main Aug 25, 2026
25 checks passed
@rbuergi
rbuergi deleted the fix/2155-pandas-explorer-follows-overlay-redirect branch August 28, 2026 08:56
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.

Flake: PandasExplorerLayoutAreaTest.Explorer_NoPythonNode_RendersToolbarAndDegradesGridWithoutHanging — 50s wait ends on the LiveFrame RedirectControl

2 participants