Skip to content

Read cached thumbnails independently of generation - #120

Open
k-kostin wants to merge 2 commits into
omacom:mainfrom
k-kostin:codex/thumbnail-cache-lane
Open

k-kostin wants to merge 2 commits into
omacom:mainfrom
k-kostin:codex/thumbnail-cache-lane

Conversation

@k-kostin

Copy link
Copy Markdown

Summary

A ready disk-cache PNG currently waits behind running video/PDF/image generation in the provider's one pool. Probe cache entries in a separate two-worker pool; send misses to the existing generation pool, where freshness/cache is checked again. Text pages go straight to their existing generation route.

image request → background cache lookup → fresh PNG: finish
                                    → miss: existing generation queue

No disk access moves to the UI thread, no RAM cache or dependency is added, and generation concurrency remains unchanged. A missing PNG is detected before querying source metadata, avoiding an extra network-source lookup on ordinary cold misses. Cache freshness uses the existing policy.

A response is separate from runnable tasks. Cancellation is checked around the cache stage and before queued generation; destruction drains cache work before generation because cache misses may still enqueue jobs. Every response finishes once. This does not import #117's running-helper cancellation.

Evidence

  • Before: with real generators held in every slot, an existing disk PNG cannot make a QML Image ready before the gate opens. After: it becomes Ready while generators are still held. The test observes persistent QML state, not a racy finished-signal subscription.
  • Eight alternating pairs per direct-provider scenario after warm-up: busy-cache response median 507.9 → 0.57 ms, p95 508.5 → 0.59 ms. This deliberately holds generators for 500 ms; these are response completion times, not displayed-frame latency.
  • Eight 12 MP synthetic JPEGs (baseline/progressive mix), cold thumbnail cache: all responses 210.7 → 209.8 ms median. Idle warm-cache batch: 1.33 → 2.33 ms, reflecting the two-reader bound; first response stays about 0.7 ms. Warm OS page cache throughout.
  • Real Backend/FolderGrid, three pairs each: all eight pictures 227.0 → 227.6 ms, jump to the last of 512 entries 353.3 → 350.2 ms, navigation during generation 43.20 → 43.26 ms. All 18 measured runs complete and drain without failure markers. Offscreen Qt Quick software rendering; physical frame latency was not measured.
  • Release build, diff check and complete local tests: 198 passed, 0 failed, using Qt image plugins matching CI dependencies. Tests cover stale/corrupt/missing cache, removed source, cache recursion and 64 cancelled queued misses.
  • ASan/UBSan with rapid real QML creation/cancellation: candidate 2378 and base 2377 requests all finished and were destroyed while the reader remained alive; no sanitizer errors (leak detection disabled). Immediate engine destruction instead leaves a few responses undestroyed on both versions; that boundary remains recorded and is not fixed here.

Merge Danger

Door: two-way.

Blast Radius: thumbnail admission. Two additional bounded workers can themselves wait on slow cache/source I/O; the existing generation limit is preserved. Pending #67/#117 changes will need the usual rebase and validation before integrating on their final base. This PR targets main independently; #67/#117 are not base dependencies.

@greptile-apps

greptile-apps Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

Separates disk-cache reads from thumbnail generation so cached pictures do not wait behind busy generators.

  • File grids and previews can load cached thumbnails while other files are still being generated.

Acknowledged limits:

  • k-kostin notes that slow cache/source I/O can occupy both cache workers.
  • k-kostin records responses left undestroyed during immediate engine destruction on both versions; that boundary is intentionally outside this change.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Request[Thumbnail request] --> Kind{Text page?}
    Kind -->|Yes| Generate[Existing generation pool]
    Kind -->|No| Cache[Two-worker cache pool]
    Cache --> Fresh{Fresh cached image?}
    Fresh -->|Yes| Finish[Finish response]
    Fresh -->|No| Generate
    Generate --> Recheck[Check cache again and generate if needed]
    Recheck --> Finish
Loading

Reviews (1) · Last reviewed commit: "Observe fast cache completion through QM..." · Reviewed by Greptile

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