@@ -25,29 +25,37 @@ const serving = (dir) => existsSync(join(dir, ".hyperframes")) && readdirSync(jo
2525async function waitFor ( cond , ms ) { const end = Date . now ( ) + ms ; while ( ! cond ( ) ) { if ( Date . now ( ) > end ) return false ; await sleep ( 200 ) ; } return true ; }
2626const env = { ...process . env , HYPERFRAMES_NO_TELEMETRY : "1" , CI : "" } ;
2727delete env . CI ;
28+ const alive = ( pid ) => { try { process . kill ( pid , 0 ) ; return true ; } catch { return false ; } } ;
2829async function scenario ( kind ) {
2930 const dir = hangProject ( ) ;
30- const base = count ( ) ;
31+ const base = new Set ( pids ( ) ) ;
32+ const mine = ( ) => pids ( ) . filter ( ( p ) => ! base . has ( p ) ) ;
3133 let victim ;
3234 if ( kind === "warm" ) {
3335 victim = spawn ( process . execPath , [ "dist/warmCheck.js" , "60000" , dir , "--json" , "--samples=1" , "--no-browser-gpu" ] , { cwd : cli , env, stdio : "ignore" } ) ;
34- await waitFor ( ( ) => count ( ) > base , 30_000 ) ;
36+ await waitFor ( ( ) => mine ( ) . length > 0 , 30_000 ) ;
3537 await sleep ( 2000 ) ;
3638 const client = spawn ( process . execPath , [ "bin/hyperframes.mjs" , "check" , dir , "--json" , "--samples=1" , "--no-browser-gpu" ] , { cwd : cli , env, stdio : [ "ignore" , "pipe" , "pipe" ] } ) ;
3739 client . stdout . on ( "data" , ( ) => { } ) ; client . stderr . on ( "data" , ( ) => { } ) ;
40+ scenario . client = client ;
3841 } else {
3942 victim = spawn ( process . execPath , [ "bin/hyperframes.mjs" , "check" , dir , "--json" , "--samples=1" , "--no-browser-gpu" ] , { cwd : cli , env : { ...env , CI : "1" } , stdio : [ "ignore" , "pipe" , "pipe" ] } ) ;
4043 victim . stdout . on ( "data" , ( ) => { } ) ; victim . stderr . on ( "data" , ( ) => { } ) ;
4144 }
4245 const busy = await waitFor ( ( ) => serving ( dir ) , 60_000 ) ;
4346 await sleep ( 3000 ) ;
44- const during = count ( ) ;
47+ const during = mine ( ) ;
4548 process . kill ( victim . pid , "SIGKILL" ) ;
46- await sleep ( 5000 ) ;
47- const after = count ( ) ;
48- console . log ( `ORPHANS ${ process . platform } ${ kind } : busy=${ busy } baseline=${ base } during=${ during } 5s-after-kill=${ after } ${ after > base ? "SURVIVORS" : "clean" } ` ) ;
49- // clean up whatever survived so the next scenario starts from zero
50- for ( const pid of pids ( ) ) { try { process . kill ( pid , "SIGKILL" ) ; } catch { } }
49+ const report = [ ] ;
50+ for ( const at of [ 5 , 15 , 30 ] ) {
51+ await sleep ( at === 5 ? 5000 : at === 15 ? 10000 : 15000 ) ;
52+ report . push ( `${ at } s:${ during . filter ( alive ) . length } ` ) ;
53+ }
54+ const left = during . filter ( alive ) . length ;
55+ console . log ( `ORPHANS ${ process . platform } ${ kind } : busy=${ busy } tracked=${ during . length } survivors ${ report . join ( " " ) } ${ left ? "SURVIVORS" : "clean" } ` ) ;
56+ for ( const pid of [ ...pids ( ) . filter ( ( p ) => ! base . has ( p ) ) , scenario . client ?. pid ] . filter ( Boolean ) ) { try { process . kill ( pid , "SIGKILL" ) ; } catch { } }
57+ scenario . client = undefined ;
5158 await sleep ( 2000 ) ;
5259}
53- for ( const kind of [ "cold" , "warm" , "cold" , "warm" ] ) await scenario ( kind ) ;
60+ const kinds = process . argv [ 2 ] === "port" ? [ "cold-port" , "cold-port" ] : [ "cold" , "warm" , "cold" , "warm" ] ;
61+ for ( const kind of kinds ) await scenario ( kind ) ;
0 commit comments