Pandas Explorer wait FOLLOWS the overlay's redirect instead of dying on it (#2155) - #2280
Conversation
…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>
There was a problem hiding this comment.
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 aRedirectControlis observed (bounded byMaxRedirectHops). - 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.
…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>
|
CI red on Not this diff, and not re-runnable. This PR changes exactly one file, Waiting for the re-pin (#2288 / #2284) to land on |
…rer-follows-overlay-redirect
Closes #2155.
PandasExplorerLayoutAreaTest.Explorer_NoPythonNode_RendersToolbarAndDegradesGridWithoutHangingspends its whole 50 s budget on a
RedirectControland fails. Three occurrences in the last 300MeshWeaver Build and Testruns (2026-08-24 14:18, 2026-08-25 09:43, 2026-08-25 18:32), each on abranch 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), theLiveFrameinstance activates against the compilation-in-progress overlay, which servesNodeTypeLayoutAreas.CompileProgressViewon EVERY area. When the build landsOkthat view emitsa
RedirectControl— and the same event recycles the instance hub:WithOverlaySelfHealpostsa
DisposeRequestto 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:
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
DispatchViewanswers aRedirectControlwithNavigationManager.NavigateTo(href), i.e.a fresh area subscription. Every wait now goes through a
Rendered(...)helper that, on aRedirectControl, re-subscribes from a fresh client hub. A new client is this test'snavigation: 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 sameclient 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.
MaxRedirectHopsbounds it so an instance stuck in an overlay↔heal loop still failsinside the 50 s budget instead of spinning.
RED before / GREEN after — deterministic, no timing
InFlightOverlayGracewas temporarily set to 1 ms locally, which forces the overlay path CI onlyreaches under load:
mainLast of 6 emission(s) was: RedirectControl … Href = /Doc/.../LiveFrame/Explorer(the issue's text, verbatim)[Explorer] compile-progress overlay redirected to … — re-subscribing (2 hop(s) left)The grace change was only a probe; it is not in this diff (
git diff origin/main...HEAD --statisone 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
LayoutAreaViewis keyedon the stream identity
(Address, Reference)— which the redirect does not change — soNavigateTo(sameUrl)need not remount it, andWorkspace._remoteStreamCachewould hand theremounted 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