Skip to content

Keep directory sizing responsive and finalize recursive Size order - #1

Open
frasergr wants to merge 3 commits into
mainfrom
perf/async-dirsize
Open

frasergr wants to merge 3 commits into
mainfrom
perf/async-dirsize

Conversation

@frasergr

@frasergr frasergr commented Sep 14, 2026 •

Copy link
Copy Markdown
Owner

Problem

Recursive directory sizes currently run inline on Flea's backend request loop. A large folder can therefore delay navigation, window refreshes, and clicks on another sort column for up to the walk's two-second deadline.

Size sorting also stops at a provisional order: files use exact metadata sizes, but folders remain in name order after their recursive sizes arrive.

Fix

  • Run at most one recursive directory-size walk off the request loop, so list, sort, window, cancellation, and shutdown remain responsive.
  • Check cancellation throughout traversal and preserve the existing two-second deadline and partial lower-bound behavior.
  • Invalidate work by cache/row generation when a list or sort renumbers rows, preventing stale results from being published against reused indices.
  • Keep completed values in a path-keyed cache and refresh visible directory cells after ordinary sorting.
  • For Size sorting, queue each folder once, retain the immediate provisional response, then apply all recursive keys in one final reorder.
  • Emit dirsorted after that reorder; the QML client clears row-indexed state, resets to row zero, requests the final window, and refills visible sizes from cache.
  • Extend protocol coverage for cancellation, stale-result suppression, cache reuse, sort responsiveness, partial results, and deterministic final ordering.

Behavior preserved

  • One directory walk at a time; no thread pool and no additional process.
  • Symlinks are not followed.
  • Viewport-only requests remain cancellable.
  • Permission failures and timeouts still return an explicitly partial lower bound.
  • Folder grouping, sort direction, and name tie-breaking remain deterministic.

Validation

  • Backend protocol suite passed.
  • QML/JavaScript checks: 3,101 passed.
  • Ordering checks: 3 passed.
  • Directory-size checks: 7 passed.
  • Release build and file-budget gate passed.
  • git diff --check passed.
  • Full Rust run: 605 passed; one trash-recovery case failed in the full environment and passed when rerun in isolation.

Relationship to upstream PR thisisgm#118

Upstream PR #118 solves the same primary responsiveness bug with a smaller persistent-worker implementation. It covers off-loop traversal, cooperative cancellation, stale-result rejection, and shutdown behavior.

This branch adds behavior thisisgm#118 does not currently implement:

  1. completed recursive sizes become the actual keys for a final Size reorder;
  2. dirsorted tells the client that row indices changed;
  3. QML clears stale row-indexed cells and fetches the final window;
  4. directory sizes are refreshed correctly after other sorts.

If thisisgm#118 merges first, the minimal upstream path is to keep its worker and port only those exact-order/client-refresh pieces rather than merge both worker implementations.

Related but outside this PR: #144 is the same event-loop blocking class in synchronous MTP/GVFS scan(), not dirsize.

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