Skip to content

fix(perf): run network git ops off the main thread#6

Merged
jcardonne merged 1 commit into
mainfrom
fix/pull-fetch-ui-freeze
Jul 12, 2026
Merged

fix(perf): run network git ops off the main thread#6
jcardonne merged 1 commit into
mainfrom
fix/pull-fetch-ui-freeze

Conversation

@jcardonne

Copy link
Copy Markdown
Owner

Problem

Selecting a pull/fetch action (or pushing) froze the UI for a few seconds before the action completed - a visible stutter, not smooth.

Cause

push, push_force, pull, fetch were bare #[tauri::command], so Tauri ran their bodies on the main/IPC thread. Their blocking remote IO (git subprocess over the network) blocked the webview for the whole operation. Every other heavy command already uses #[tauri::command(async)] (worker thread) - the network ops were missed.

Fix

  • Mark the four network commands (async) so they run off the main thread. The synchronous bodies each own their own Repository and never await, so the spawned future is Send (same invariant the existing async commands rely on).
  • Bare commands were implicitly serialized on the IPC thread; (async) removes that, so a rapid double-trigger (e.g. the pull/push keyboard shortcut hit twice) could now launch two concurrent git ops racing on the same .git lock files. Add a synchronous re-entrancy guard in RepoView.run() using busyRef (not the render-lagged busy state) so only one op runs at a time, regardless of trigger (button or keyboard).
  • Drop the now-redundant busy->busyRef mirror effect; run() owns busyRef directly.

Verification

  • cargo check clean
  • tsc --noEmit clean
  • Concurrency hazard surfaced by a code-review pass; guard added in response.

push/push_force/pull/fetch were bare #[tauri::command], so their
blocking remote IO ran on the main/IPC thread and froze the webview
for seconds - visible as a UI stutter when picking a pull/fetch action.
Mark them (async) like the other heavy commands so they run on a worker
thread.

That removes the implicit backend serialization those blocking commands
had, so add a synchronous re-entrancy guard in RepoView.run() (busyRef,
not the render-lagged busy state) so a rapid double-trigger - e.g. the
pull/push keyboard shortcut hit twice - can't launch two concurrent git
ops racing on the same .git lock files. The now-redundant busy->busyRef
mirror effect is dropped; run() owns busyRef directly.
@jcardonne
jcardonne merged commit 60d84d6 into main Jul 12, 2026
2 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.28.3 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@jcardonne
jcardonne deleted the fix/pull-fetch-ui-freeze branch July 12, 2026 22:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant