Repository navigation
Conversation
Every scope change in the main process scheduled its own setImmediate that rebuilt the event defaults by running every event processor. ElectronContext calls the synchronous app.getAppMetrics(), which costs about 0.04 ms per process, so a burst of breadcrumbs blocked the main thread for seconds in apps with many processes. Scope changes now coalesce into one save on the next event loop turn and the event defaults are rebuilt at most every 5 seconds. A save that reused cached defaults schedules one catch-up save at expiry so context that only exists after the app is ready, such as screen and GPU details, still reaches the stored scope and the crash reporter parameters. Both the Sentry and the Electron minidump uploader paths use the new helper. In the Electron uploader path the event build is now synchronous, so the epoch guard is gone. Fixes #1467
A defaults fetch that outlives the cache window lets a later save start a second fetch. If the second one resolves first, the older save would write an older scope over the newer one. Each run now records its sequence number and skips its save when a newer run has started.
addScopeListener builds the merged scope inside each of the three scope listeners before it calls back, which copies both breadcrumb arrays on every change. The saver only keeps the last scope of a turn, so that work was wasted. The saver now takes a scope getter and reads it once when the save runs, and the minidump integrations subscribe through a new onScopeChange that passes nothing.
Screen and GPU context only exist after app ready. When the first scope change ran before that, the defaults were cached without them and a native crash in the next five seconds carried incomplete context. The saver now exposes refresh, which drops the cached defaults and saves again, and both minidump integrations call it from app.whenReady(). The catch-up timer at expiry is gone because this covers the case it was added for.
JPeer264
approved these changes
Oct 16, 2026
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.
Backport of #1468 to v7. All commits cherry-picked without changes.
Fixes #1467
Every scope change in the main process rebuilt the event defaults by running every event processor, including the synchronous
app.getAppMetrics()(about 0.04 ms per process), and built the merged scope three times over. A burst ofconsole.logcalls or forwarded renderer breadcrumbs blocked the main thread for seconds in apps with many processes.A new
createScopeSavermerges the scope changes of one event loop turn into a single save on the next turn, reads the merged scope once when that save runs, and rebuilds the defaults only when they are older than 5 seconds. Both minidump integrations call itsrefreshfromapp.whenReady(), because screen and GPU context only exist once the app is ready. A sequence number stops a slow older save from writing over a newer one.onScopeChangeincommon/scope.tsregisters a bare callback on the three scopes;addScopeListeneris unchanged for the renderer. The Electron uploader path now builds its event synchronously, so its epoch guard is gone.Unit tests cover coalescing, the single scope read, caching,
refresh, the stale-save guard and rejection handling. The reproduction from the issue now makes zeroapp.getAppMetrics()calls for 5,000console.logcalls and the main thread is busy for about 18 ms instead of seconds (about 12 ms with no SDK). The full native crash e2e suite passes on Electron 39.8.10.app.getAppMetrics()still runs once per real event throughElectronContext; whether the app-wide memory figure is worth keeping is a separate question.