返回 DeepSeek-Reasonix
smoke-lifecycle.mjs
根目录 / desktop / packaging / smoke-lifecycle.mjs
1 export const sleep = (ms) => new Promise((done) => setTimeout(done, ms));
2
3 export function processAlive(pid) {
4 if (!Number.isInteger(pid) || pid <= 0) throw new Error(`invalid process id: ${pid}`);
5 try {
6 process.kill(pid, 0);
7 return true;
8 } catch (error) {
9 if (error.code === "ESRCH") return false;
10 throw error;
11 }
12 }
13
14 export async function waitForProcessesToExit(pids, timeout = 5_000) {
15 const deadline = Date.now() + timeout;
16 let remaining;
17 while ((remaining = pids.filter(processAlive)).length > 0) {
18 if (Date.now() >= deadline) throw new Error(`processes outlived normal app quit: ${remaining.join(", ")}`);
19 await sleep(100);
20 }
21 }
22
23 // ElectronApplication.close invokes app.quit and waits for the application to
24 // close. A timeout is a failed smoke, never evidence that forced cleanup worked.
25 export async function closeAndVerify(application, { shellPid, servicePid }, timeout = 15_000) {
26 let timer;
27 try {
28 await Promise.race([
29 application.close(),
30 new Promise((_, reject) => {
31 timer = setTimeout(() => reject(new Error(`normal app quit did not complete within ${timeout / 1000}s`)), timeout);
32 }),
33 ]);
34 } finally {
35 clearTimeout(timer);
36 }
37 await waitForProcessesToExit([shellPid, servicePid]);
38 }
39
39 lines Plain Text