Skip to content

Harden GL context-loss recovery and gate dashboard reliability in CI - #5

Merged
Alek99 merged 1 commit into
mainfrom
codex/rendering-hardening
Jul 9, 2026
Merged

Harden GL context-loss recovery and gate dashboard reliability in CI#5
Alek99 merged 1 commit into
mainfrom
codex/rendering-hardening

Conversation

@Alek99

@Alek99 Alek99 commented Jul 9, 2026

Copy link
Copy Markdown
Member

Summary

  • 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 the latest payload
  • 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/context_restore_failed chart events
  • The dependency-free render smoke 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.py 10/20/50 must produce a loss-free, fully nonblank 10-chart row within catastrophic budgets, enforced by verify_benchmark_report.py
  • Interaction and visual budgets are pinned in the verifier so a benchmark change cannot silently relax its own gate
  • 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 --check passes and no longer stops CI before browser tests

Validation

  • cargo build --release
  • pytest -q: 888 passed (8 new tests, including negative paths for every new gate)
  • ruff check ., ruff format --check . (now clean repo-wide), ty check
  • scripts/render_smoke_nonumpy.py: 3 recovery cycles, all pixel hashes identical, quiescence and post-restore zoom verified
  • scripts/visual_regression_smoke.py: 9 charts, 18 assets, 2 chrome shells OK
  • CI gate end-to-end: dashboard 10/20/50 run → 10-chart row complete (0 losses), 20/50 partial with metrics retained → verify_benchmark_report --kind dashboard-browser passes
  • Notebook change verified formatting-only: all 16 code cells AST-identical, markdown unchanged

Notes 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

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.
@Alek99
Alek99 merged commit 3e6295e into main Jul 9, 2026
4 of 7 checks passed
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>
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.

1 participant