Skip to content

Paint the TUI on launch before the PDF engine loads, and boot every PDF worker with SIGINT held - #221

Merged
ben-dev-au merged 2 commits into
mainfrom
feat/tui-launch-before-query
Oct 21, 2026
Merged

ben-dev-au merged 2 commits into
mainfrom
feat/tui-launch-before-query

Conversation

@ben-dev-au

Copy link
Copy Markdown
Owner

Summary

  • fnd tui "<query>" now paints its first frame before anything loads pymupdf, so the window appears straight away and the progress bar shows the work.
  • The one-time texture-cache key promotion moves out of on_mount into _promote_texture_cache_keys, run after the first refresh. Once its sentinel exists it never imports the PDF engine at all.
  • warm_pool no longer waits for the worker to boot. submit still spawns the process while the FD table is clean, which is all the macOS fds_to_keep fix needed.
  • Every PDF worker spawn, including a respawn after a crash or stall, now boots with SIGINT blocked (_sigint_held). The initializer sets SIG_DFL and only then unblocks, so a ^C that lands mid-boot ends the worker quietly instead of printing a KeyboardInterrupt traceback (the Quit cleanly on Ctrl+C: no traceback from the PDF worker or teardown #218 guarantee, previously covered only for the first spawn).

Tests

  • tests/test_launch_paints_before_the_pdf_engine.py: a tripwire module stands in for fnd.extract.pdf; a promoted cache reads nothing from it, an unpromoted one does (control), and the promotion runs only after on_mount returns.
  • tests/test_worker_sigint_is_silent.py: a FIFO trace file holds a booting worker before its initializer, the test sends SIGINT, then releases it. Covers the warm spawn and a respawn through run_in_pool_sync_with_stall_detection. Both fail without the mask (negative controls run), and neither can hang: the reader is non-blocking and outlives pool shutdown.
  • make batch-close green on this tree: 6366 passed, 5 skipped; ruff and pyright clean; 12 tmux scenarios passed (1 skipped).

Notes

  • Windows has no signal mask, so warm_pool keeps waiting for the boot there; a respawn on Windows still has the ^C boot gap.
  • run_in_pool and run_in_pool_sync have no callers; left alone as out of scope.

Launching with a query looked frozen until results arrived. The search
already runs off the loop; what held the first frame was launch work
ahead of it.

- The PDF-texture key promotion runs after the first frame and checks
  its sentinel before importing the PDF extractor, so a normal launch no
  longer loads pymupdf's native libraries before painting.
- `warm_pool` spawns the PDF worker without waiting for it to boot:
  `submit` spawns synchronously, which is all the FD-table constraint
  needs. SIGINT is held across the spawn and unblocked in the worker's
  initializer, so a ^C during the boot still ends it silently. Windows,
  with no signal mask, keeps the wait.

On an evicted page cache, on_mount fell from 0.46 to 0.57s to 0.16 to
0.18s, and the first frame from 1.66 to 2.69s to 1.02 to 1.61s.
A worker respawned after a crash, stall or stale-FD recovery was
spawned from an extraction thread with SIGINT unblocked, so a ^C during
its boot printed a KeyboardInterrupt traceback over the TUI before its
initializer could install SIG_DFL.

Every submit now goes through `_submit`, which holds SIGINT across the
call; holding it costs nothing when no spawn happens. Windows has no
signal mask and keeps the gap.
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 7e16a73e-fc3e-4a89-a4bf-6160dda98600
📥 Commits

Reviewing files that changed from the base of the PR and between 583406b and 05fbe3e.

📒 Files selected for processing: 4
  • fnd/extract/_worker.py
  • fnd/tui/app.py
  • tests/test_launch_paints_before_the_pdf_engine.py
  • tests/test_worker_sigint_is_silent.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

Worker-pool submissions now protect worker startup from SIGINT. Texture-cache key promotion now runs after the first UI refresh. Tests cover worker startup signals and cache-promotion timing and PDF-engine access.

Changes: Worker SIGINT Handling

Layer / File(s) Summary
Protected worker startup
fnd/extract/_worker.py
Pool startup is submitted while SIGINT is blocked. Workers unblock SIGINT after initialisation. warm_pool handles platforms with and without signal-mask support.
Protected submission paths and signal tests
fnd/extract/_worker.py, tests/test_worker_sigint_is_silent.py
run_in_pool, run_in_pool_sync, and stall-detection submissions use _submit. Tests cover SIGINT during initial and respawned worker startup.

Deferred Texture-Cache Promotion

Layer / File(s) Summary
Deferred cache promotion and lifecycle checks
fnd/tui/app.py, tests/test_launch_paints_before_the_pdf_engine.py
on_mount schedules cache promotion after the first refresh. Tests check PDF-engine access for promoted and unpromoted caches, and verify the promotion timing.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 05fbe

The deferred worker startup does not appear to block the affected startup or extraction paths. The change is ready to merge after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 53.85% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 26 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly summarises both primary changes: early TUI painting and SIGINT protection during PDF worker startup.
Description check Passed The description directly explains the TUI cache migration, worker SIGINT handling, platform-specific behaviour, scope, and test coverage.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

I’m a rabbit, watching workers start,
SIGINT waits until their boot is through.
The first refresh comes, then keys are checked,
Tests trace the timing and engine too.
I twitch my nose at orderly flows,
And hop away when checks pass through.

Comment @coderabbitai help to get the list of available commands.

@ben-dev-au
ben-dev-au merged commit 553c3a4 into main Oct 21, 2026
22 checks passed
@ben-dev-au
ben-dev-au deleted the feat/tui-launch-before-query branch October 21, 2026 12:03
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