mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
fix(engine): preserve Windows RSS samples after a query failure (#5357)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { sampleProcessRss } from "../utils/processRss.js";
|
||||
import {
|
||||
createChromeMemorySampler,
|
||||
mergeSample,
|
||||
@@ -170,6 +171,31 @@ describe("createChromeMemorySampler", () => {
|
||||
expect(sampler.stats()).toEqual(empty);
|
||||
});
|
||||
|
||||
it("reports Windows browser and GPU memory when the renderer query fails", async () => {
|
||||
const exec = async (_file: string, args: readonly string[]) => {
|
||||
const pid = Number(args[4]?.slice("PID eq ".length));
|
||||
if (pid === 2) throw new Error("tasklist timed out");
|
||||
return { stdout: `"chrome.exe","${pid}","Console","1","${pid * 10240} K"\r\n` };
|
||||
};
|
||||
const onSample = vi.fn();
|
||||
const sampler = createChromeMemorySampler({
|
||||
getPids: async () => ({ browser: 1, renderers: [2], gpu: [3] }),
|
||||
sampleRss: (pids) => sampleProcessRss(pids, exec, "win32"),
|
||||
intervalMs: 100,
|
||||
onSample,
|
||||
});
|
||||
|
||||
await sampler.sampleOnce();
|
||||
expect(sampler.stats()).toEqual({
|
||||
browserRssPeakMb: 10,
|
||||
rendererRssPeakMb: undefined,
|
||||
rssLastMb: 40,
|
||||
gpuProcessSeenLastSample: true,
|
||||
samples: 1,
|
||||
});
|
||||
expect(onSample).toHaveBeenCalledWith(sampler.stats());
|
||||
});
|
||||
|
||||
it("unrefs the interval so a forgotten stop() cannot hold the process open", () => {
|
||||
// Real timers: a real NodeJS.Timeout reports hasRef(); the interval is far
|
||||
// enough out that no tick fires during the test.
|
||||
|
||||
@@ -115,6 +115,21 @@ describe("sampleProcessRss", () => {
|
||||
expect(result).toEqual([{ pid: 9, rssMb: 2 }]);
|
||||
});
|
||||
|
||||
it.each([1, 2, 3])("keeps successful Windows samples when pid %i fails", async (failedPid) => {
|
||||
const calls: number[] = [];
|
||||
const exec = async (_file: string, args: readonly string[]) => {
|
||||
const pid = Number(args[4]?.slice("PID eq ".length));
|
||||
calls.push(pid);
|
||||
if (pid === failedPid) throw new Error("tasklist timed out");
|
||||
return { stdout: `"chrome.exe","${pid}","Console","1","${pid * 1024} K"\r\n` };
|
||||
};
|
||||
|
||||
expect(await sampleProcessRss([1, 2, 3], exec, "win32")).toEqual(
|
||||
[1, 2, 3].filter((pid) => pid !== failedPid).map((pid) => ({ pid, rssMb: pid })),
|
||||
);
|
||||
expect(calls).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it("drops invalid pids and duplicates before calling ps", async () => {
|
||||
const calls: Array<readonly string[]> = [];
|
||||
const exec = async (_file: string, args: readonly string[]) => {
|
||||
|
||||
@@ -91,8 +91,10 @@ export async function sampleProcessRss(
|
||||
if (platform === "win32") {
|
||||
const results: ProcessRssSample[] = [];
|
||||
for (const pid of unique) {
|
||||
const { stdout } = await exec("tasklist", ["/FO", "CSV", "/NH", "/FI", `PID eq ${pid}`]);
|
||||
results.push(...parseTasklistCsv(pid, stdout));
|
||||
try {
|
||||
const { stdout } = await exec("tasklist", ["/FO", "CSV", "/NH", "/FI", `PID eq ${pid}`]);
|
||||
results.push(...parseTasklistCsv(pid, stdout));
|
||||
} catch {}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user