Repository navigation
Send update download progress on a small throttled event - #1072
Merged
Merged
Conversation
Each network chunk of an update download locked the shared state and emitted the whole AppState, running the diagnostics and telemetry observers, resetting the tray text and re-rendering the webview. A large installer meant thousands of these and could freeze the app. Bytes are now counted atomically outside the state mutex and sent on an update-progress event at most every 250 ms and only when the whole percent changes, with the completing sample always sent. Full state is emitted only for status transitions, with the final size at ready. The tray skips mutations whose value has not changed, and a downloading entry is recorded in the diagnostic history. Closes #1071 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Updates tab mounted its own progress listener, so opening it during a download showed zero until the next throttled sample. App now owns the single listener and passes the merged updater state to the banner and the Updates tab. The tray cache recorded values before the native setters ran, so a failed call left the tray stale. Each value is now recorded only after its setter succeeds. Refs #1071 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
enaboapps
marked this pull request as ready for review
October 15, 2026 11:23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1071
Summary
The download progress callback emitted the full
AppStatefor every network chunk: two snapshots, diagnostics and telemetry observers, a trayset_text, and a full webview re-render. A ~155 MB installer meant thousands of these, which could freeze the app.updater::ProgressCountercounts bytes inAtomicU64s outside the shared state mutex.update-progressevent carries{ downloadedBytes, totalBytes }.updater::ProgressThrottle(pure, injectableInstant) emits the first sample, then only when ≥250 ms have passed and the whole percent has changed (time alone when the total is unknown). The completing sample is always emitted once.publish_update/emit_statenow happens only on transitions (downloading, ready, failed, cancelled). The final byte count and total go intoAppState.updaterat ready.UpdateView::add_progressis removed.TrayController::syncskipsset_text/set_enabledwhen the native menu already shows the value. Each value is recorded only after its setter succeeds, so a failed call is retried on the next sync.downloadingupdater entry is recorded when a download starts.App(always mounted) callsuseUpdateProgressonce, giving a singleapi.onUpdateProgresslistener. It passes the merged updater state to theUpdateBannerand, throughSettingsView, toUpdatesSection, so opening Updates mid-download shows the latest sample. Stale samples are cleared when a download ends. The UI text is unchanged.Validation
Latest head, Node 24.19.0, Rust 1.97.1, Windows 11:
npm run prediction-model: verified offline neural model and workersnpm run lint: passnpm test: vitest 13 files / 299 tests passed; node tests 12/12 passednpm run build: passcargo fmt --manifest-path src-tauri/Cargo.toml --check: passcargo clippy --manifest-path src-tauri/Cargo.toml --all-targets -- -D warnings: passcargo test --manifest-path src-tauri/Cargo.toml: 790 passed, 5 ignored; 7 passed in the integration suiteNew tests:
🤖 Generated with Claude Code