Improve attachment memory safety, downloads, and high-memory alert UX.
All checks were successful
Queue Release Build / prepare (push) Successful in 20s
Deploy Web Apps / deploy (push) Successful in 9m2s
Queue Release Build / build-windows (push) Successful in 28m8s
Queue Release Build / build-linux (push) Successful in 47m26s
Queue Release Build / build-android (push) Successful in 19m52s
Queue Release Build / finalize (push) Successful in 4m42s
All checks were successful
Queue Release Build / prepare (push) Successful in 20s
Deploy Web Apps / deploy (push) Successful in 9m2s
Queue Release Build / build-windows (push) Successful in 28m8s
Queue Release Build / build-linux (push) Successful in 47m26s
Queue Release Build / build-android (push) Successful in 19m52s
Queue Release Build / finalize (push) Successful in 4m42s
Stream large receives to disk with chunk acks to cap renderer RAM, evict off-screen display blobs, and route exports through a disk-aware download service. Fix the high-memory dialog (backdrop dismiss, copy, log actions), allow diagnostics paths in the path jail, and restore persisted image hydration after reload. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
80
electron/diagnostics/high-memory-capture.ts
Normal file
80
electron/diagnostics/high-memory-capture.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import type { BrowserWindow } from 'electron';
|
||||
import type { AppMetricsSnapshot } from '../app-metrics';
|
||||
import { buildHighMemoryDiagnosticPayload } from './high-memory-snapshot.rules';
|
||||
import { collectImmediateRendererSamples } from './immediate-renderer-samples.collector';
|
||||
import { collectSessionContext } from './session-context.collector';
|
||||
import type { HighMemoryAlertRecord } from './high-memory-alert.store';
|
||||
import type { PerfDiagEntry } from './diagnostics.models';
|
||||
import { PerfDiagWriter } from './diagnostics.writer';
|
||||
|
||||
export type HighMemoryCaptureReason = 'manual' | 'threshold';
|
||||
|
||||
export interface CaptureHighMemoryDiagnosticsInput {
|
||||
userDataPath: string;
|
||||
sessionStartedAt: number;
|
||||
metrics: AppMetricsSnapshot;
|
||||
totalWorkingSetKb: number;
|
||||
writer: PerfDiagWriter | null;
|
||||
mainWindow: BrowserWindow | null;
|
||||
reason: HighMemoryCaptureReason;
|
||||
}
|
||||
|
||||
export async function captureHighMemoryDiagnostics(
|
||||
input: CaptureHighMemoryDiagnosticsInput
|
||||
): Promise<HighMemoryAlertRecord> {
|
||||
const detectedAt = Date.now();
|
||||
const writer = input.writer ?? new PerfDiagWriter({
|
||||
userDataPath: input.userDataPath,
|
||||
sessionId: `${input.reason}-${detectedAt.toString(36)}-${process.pid}`
|
||||
});
|
||||
const immediateRendererEntries = await collectImmediateRendererSamples(input.mainWindow);
|
||||
const environment = collectSessionContext({
|
||||
sessionStartedAt: input.sessionStartedAt,
|
||||
userDataPath: input.userDataPath
|
||||
});
|
||||
|
||||
appendEntries(writer, immediateRendererEntries);
|
||||
appendEntries(writer, [
|
||||
{
|
||||
collectedAt: detectedAt,
|
||||
source: 'main',
|
||||
type: 'environment',
|
||||
payload: {
|
||||
...environment
|
||||
}
|
||||
},
|
||||
{
|
||||
collectedAt: detectedAt,
|
||||
source: 'main',
|
||||
type: 'high-memory',
|
||||
payload: buildHighMemoryDiagnosticPayload({
|
||||
detectedAt,
|
||||
totalWorkingSetKb: input.totalWorkingSetKb,
|
||||
metrics: input.metrics,
|
||||
environment,
|
||||
mainProcessMemory: process.memoryUsage(),
|
||||
ringEntries: writer.bufferedEntries,
|
||||
immediateRendererEntries,
|
||||
sessionId: writer.sessionId
|
||||
})
|
||||
}
|
||||
]);
|
||||
|
||||
await writer.flushSnapshot(
|
||||
input.reason === 'manual' ? 'manual-export' : 'high-memory-threshold'
|
||||
);
|
||||
|
||||
return {
|
||||
logFilePath: writer.snapshotFilePath,
|
||||
detectedAt,
|
||||
peakWorkingSetKb: input.totalWorkingSetKb,
|
||||
sessionId: writer.sessionId,
|
||||
reason: input.reason
|
||||
};
|
||||
}
|
||||
|
||||
function appendEntries(writer: PerfDiagWriter, entries: readonly PerfDiagEntry[]): void {
|
||||
for (const entry of entries) {
|
||||
writer.append(entry);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user