chore: event-loop stall detectors for hang diagnosis
WER records AppHangTransient with no stack, so measure lag in both processes and log it on recovery: [main] event loop stalled / [renderer] main thread stalled. Tells a main-process block from a renderer freeze the next time the app 'freezes then recovers'.
This commit is contained in:
1 parent
258e5fac0c
commit
f128c3e8be
2 files changed
+25
No files matched your search
@@ -167,6 +167,18 @@ process.on('uncaughtException', (err) => {
|
|||||||
console.error('[main] uncaughtException:', err)
|
console.error('[main] uncaughtException:', err)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Diagnostics for "app froze then recovered" reports: WER logs an
|
||||||
|
// AppHangTransient but keeps no stack. A stall of THIS (UI) thread is what
|
||||||
|
// Windows flags as a hang, so measure event-loop lag and say so loudly when
|
||||||
|
// it happens — that distinguishes a main-process block from a renderer one.
|
||||||
|
let lastTick = Date.now()
|
||||||
|
setInterval(() => {
|
||||||
|
const now = Date.now()
|
||||||
|
const lag = now - lastTick - 1000
|
||||||
|
if (lag > 2000) console.error(`[main] event loop stalled ~${lag}ms`)
|
||||||
|
lastTick = now
|
||||||
|
}, 1000).unref()
|
||||||
|
|
||||||
app.on('before-quit', () => {
|
app.on('before-quit', () => {
|
||||||
// Let window 'close' events pass through so teardown completes.
|
// Let window 'close' events pass through so teardown completes.
|
||||||
markQuitting()
|
markQuitting()
|
||||||
|
|||||||
@@ -11,6 +11,19 @@ import { useSettingsStore } from './settings/store'
|
|||||||
import { mix } from './theme/chrome'
|
import { mix } from './theme/chrome'
|
||||||
import './global.css'
|
import './global.css'
|
||||||
|
|
||||||
|
// Diagnostics: report renderer main-thread freezes after recovery. console.error
|
||||||
|
// is surfaced into the dev terminal by the main process's console-message hook,
|
||||||
|
// so a "卡死又恢复" report tells us which process stalled and for how long.
|
||||||
|
{
|
||||||
|
let lastTick = performance.now()
|
||||||
|
setInterval(() => {
|
||||||
|
const now = performance.now()
|
||||||
|
const lag = now - lastTick - 2000
|
||||||
|
if (lag > 3000) console.error(`[renderer] main thread stalled ~${Math.round(lag)}ms`)
|
||||||
|
lastTick = now
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
|
||||||
// Dev convenience: allow opening the renderer in a plain browser (vite page)
|
// Dev convenience: allow opening the renderer in a plain browser (vite page)
|
||||||
// so layout/UX work doesn't require the electron shell. No-op under electron.
|
// so layout/UX work doesn't require the electron shell. No-op under electron.
|
||||||
if (typeof window !== 'undefined' && !window.api) {
|
if (typeof window !== 'undefined' && !window.api) {
|
||||||
|
|||||||
Reference in new issue
Block a user