@@ -2,6 +2,7 @@ import {writeFile} from "node:fs/promises";
22import { Session } from "node:inspector" ;
33
44let session ;
5+ let processSignals ;
56
67export async function start ( ) {
78 if ( session ) {
@@ -11,25 +12,44 @@ export async function start() {
1112 session . connect ( ) ;
1213 await new Promise ( ( resolve ) => {
1314 session . post ( "Profiler.enable" , ( ) => {
15+ console . log ( `Recording CPU profile...` ) ;
1416 session . post ( "Profiler.start" , ( ) => {
17+ processSignals = registerSigHooks ( ) ;
1518 resolve ( ) ;
1619 } ) ;
1720 } ) ;
1821 } ) ;
1922}
2023
2124async function writeProfile ( profile ) {
22- const d = new Date ( ) ;
23- const timestamp =
24- `${ d . getFullYear ( ) } -${ d . getMonth ( ) + 1 } -${ d . getDate ( ) } _${ d . getHours ( ) } -${ d . getMinutes ( ) } -${ d . getSeconds ( ) } ` ;
25+ const formatter = new Intl . DateTimeFormat ( "en-GB" , {
26+ year : "numeric" ,
27+ month : "2-digit" ,
28+ day : "2-digit" ,
29+ hour : "2-digit" ,
30+ minute : "2-digit" ,
31+ second : "2-digit" ,
32+ } ) ;
33+ const dateParts = Object . create ( null ) ;
34+ const parts = formatter . formatToParts ( new Date ( ) ) ;
35+ parts . forEach ( ( p ) => {
36+ dateParts [ p . type ] = p . value ;
37+ } ) ;
2538
26- await writeFile ( `./ui5_${ timestamp } .cpuprofile` , JSON . stringify ( profile ) ) ;
39+ const fileName = `./ui5_${ dateParts . year } -${ dateParts . month } -${ dateParts . day } _` +
40+ `${ dateParts . hour } -${ dateParts . minute } -${ dateParts . second } .cpuprofile` ;
41+ console . log ( `\nSaving CPU profile to ${ fileName } ...` ) ;
42+ await writeFile ( fileName , JSON . stringify ( profile ) ) ;
2743}
2844
2945export async function stop ( ) {
3046 if ( ! session ) {
3147 return ;
3248 }
49+ if ( processSignals ) {
50+ deregisterSigHooks ( processSignals ) ;
51+ processSignals = null ;
52+ }
3353 const profile = await new Promise ( ( resolve ) => {
3454 session . post ( "Profiler.stop" , ( err , { profile} ) => {
3555 if ( err ) {
@@ -38,8 +58,38 @@ export async function stop() {
3858 resolve ( profile ) ;
3959 }
4060 } ) ;
61+ session = null ;
4162 } ) ;
4263 if ( profile ) {
4364 await writeProfile ( profile ) ;
4465 }
4566}
67+
68+ function registerSigHooks ( ) {
69+ function createListener ( exitCode ) {
70+ return function ( ) {
71+ // Gracefully end profiling, then exit
72+ stop ( ) . then ( ( ) => {
73+ process . exit ( exitCode ) ;
74+ } ) ;
75+ } ;
76+ }
77+
78+ const processSignals = {
79+ "SIGHUP" : createListener ( 128 + 1 ) ,
80+ "SIGINT" : createListener ( 128 + 2 ) ,
81+ "SIGTERM" : createListener ( 128 + 15 ) ,
82+ "SIGBREAK" : createListener ( 128 + 21 )
83+ } ;
84+
85+ for ( const signal of Object . keys ( processSignals ) ) {
86+ process . on ( signal , processSignals [ signal ] ) ;
87+ }
88+ return processSignals ;
89+ }
90+
91+ function deregisterSigHooks ( signals ) {
92+ for ( const signal of Object . keys ( signals ) ) {
93+ process . removeListener ( signal , signals [ signal ] ) ;
94+ }
95+ }
0 commit comments