MCPcopy
hub / github.com/anomalyco/opencode / createUnresponsiveSampler

Function createUnresponsiveSampler

packages/desktop/src/main/unresponsive.ts:7–69  ·  view source on GitHub ↗
(win: BrowserWindow, name: string)

Source from the content-addressed store, hash-verified

5const samplePeriod = 15000
6
7export function createUnresponsiveSampler(win: BrowserWindow, name: string) {
8 let sampleTimer: ReturnType<typeof setTimeout> | undefined
9 let stopTimer: ReturnType<typeof setTimeout> | undefined
10 let sampling = false
11 const samples = new Map<string, number>()
12
13 const active = () => sampling && !win.isDestroyed() && !win.webContents.isDestroyed()
14 const clearTimers = () => {
15 if (sampleTimer) clearTimeout(sampleTimer)
16 if (stopTimer) clearTimeout(stopTimer)
17 sampleTimer = undefined
18 stopTimer = undefined
19 }
20
21 const schedule = () => {
22 sampleTimer = setTimeout(() => {
23 void collect()
24 }, sampleInterval)
25 }
26
27 const collect = async () => {
28 if (!active()) return
29 const stack = await win.webContents.mainFrame.collectJavaScriptCallStack().catch((error) => {
30 writeLog("window", "failed to collect unresponsive sample", { window: name, error }, "error")
31 return undefined
32 })
33 if (!active()) return
34 if (stack) samples.set(stack, (samples.get(stack) ?? 0) + 1)
35 schedule()
36 }
37
38 const stopAndFlush = () => {
39 const wasSampling = sampling
40 sampling = false
41 clearTimers()
42 if (samples.size === 0) return wasSampling
43
44 const entries = [...samples.entries()].sort((a, b) => b[1] - a[1])
45 const total = entries.reduce((sum, entry) => sum + entry[1], 0)
46 const message = [
47 "renderer unresponsive samples",
48 `Window: ${name}`,
49 `URL: ${win.isDestroyed() ? "<destroyed>" : win.webContents.getURL()}`,
50 ...entries.map((entry) => `<${entry[1]}> ${entry[0]}`),
51 `Total Samples: ${total}`,
52 ].join("\n")
53 writeLog("window", message, undefined, "error")
54 samples.clear()
55 return wasSampling
56 }
57
58 const start = () => {
59 if (sampling || win.isDestroyed() || win.webContents.isDestroyed() || win.webContents.isDevToolsOpened()) return
60 sampling = true
61 samples.clear()
62 schedule()
63 stopTimer = setTimeout(stopAndFlush, samplePeriod)
64 }

Callers 1

wireWindowRecoveryFunction · 0.90

Calls 1

onMethod · 0.80

Tested by

no test coverage detected