Harden GL context-loss recovery and gate dashboard reliability in CI - #5
Merged
Conversation
Context loss now quiesces every source of deferred GPU work (draw RAF, wheel-zoom RAF and pending zoom, view animation, view/re-bin timers) and bumps the request sequence so pre-loss kernel/worker replies cannot mutate the rebuilt context. Streamed append payloads stay canonical while the context is down; restore rebuilds all GPU state from them. A failed restore no longer throws from the event handler: it reports context_restore_failed, stays explicitly failed, and ignores later restore events on the detached canvas. Recovery state is observable via root dataset fcContextState and context_lost/context_restored events. The dependency-free render smoke now forces three loss/restore cycles with queued deferred work, asserts quiescence and pixel-identical rebuilds each cycle, and verifies post-restore interaction. CI gains a dashboard reliability smoke: bench_dashboard 10/20/50 must produce a loss-free, fully nonblank 10-chart row within catastrophic budgets, verified by verify_benchmark_report. Interaction and visual budgets are pinned in the verifier so gates cannot be silently relaxed. Timing regressions beyond 2x stay advisory; beyond 4x fail hard. Visual y-axis checks keep asset rows strict while tolerating Chromium glyph-antialias differences on generated charts. Reformatted examples/demo.ipynb (AST-identical) so repo-wide ruff format passes.
FarhanAliRaza
added a commit
that referenced
this pull request
Jul 15, 2026
- Legend now (re)freezes options and swatch scaling via _attach() when added to an axes, so a legend constructed against one axes but attached to another picks up the host's dpi/rcParams (review #1). - Legend.__init__ warns on handles/labels length mismatch and on handles without a legend entry instead of dropping them silently (review #4). - JS tracks every legend box (not just the primary) so _resize refreshes max-height on extra legends too (review #2). - JS line swatch uses ?? so an explicit lw=0 draws nothing instead of falling back to 1.5px (review #3). - Drop unreachable return in _best_legend_loc (review #5).
FarhanAliRaza
added a commit
that referenced
this pull request
Jul 15, 2026
* Improve pyplot legend and dash parity * Fix extra legend rendering regressions * Address review: legend attach recompute, resize tracking, lw=0 swatch - Legend now (re)freezes options and swatch scaling via _attach() when added to an axes, so a legend constructed against one axes but attached to another picks up the host's dpi/rcParams (review #1). - Legend.__init__ warns on handles/labels length mismatch and on handles without a legend entry instead of dropping them silently (review #4). - JS tracks every legend box (not just the primary) so _resize refreshes max-height on extra legends too (review #2). - JS line swatch uses ?? so an explicit lw=0 draws nothing instead of falling back to 1.5px (review #3). - Drop unreachable return in _best_legend_loc (review #5). --------- Co-authored-by: Alek <alek@reflex.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
context_restore_failed, stays explicitly failed, and ignores later restore events on the detached canvasroot.dataset.fcContextStateandcontext_lost/context_restored/context_restore_failedchart eventsbench_dashboard.py10/20/50 must produce a loss-free, fully nonblank 10-chart row within catastrophic budgets, enforced byverify_benchmark_report.pyexamples/demo.ipynb(AST-identical) so repo-wideruff format --checkpasses and no longer stops CI before browser testsValidation
cargo build --releasepytest -q: 888 passed (8 new tests, including negative paths for every new gate)ruff check .,ruff format --check .(now clean repo-wide),ty checkscripts/render_smoke_nonumpy.py: 3 recovery cycles, all pixel hashes identical, quiescence and post-restore zoom verifiedscripts/visual_regression_smoke.py: 9 charts, 18 assets, 2 chrome shells OKcomplete(0 losses), 20/50partialwith metrics retained →verify_benchmark_report --kind dashboard-browserpassesNotes for reviewers
The 10-chart smoke gate includes hard timing budgets (
render_ms≤ 5 s). Software-GL render is ~1.8 s on a fast Mac; GitHub's SwiftShader runners are typically 2–4× slower, so watch the first CI runs — the loss-free/nonblank gate is the load-bearing part and is timing-independent, so the budgets can be raised without weakening it if they prove noisy.🤖 Generated with Claude Code