@@ -2,6 +2,7 @@ import {writeFile} from "node:fs/promises";
2
2
import { Session } from "node:inspector" ;
3
3
4
4
let session ;
5
+ let processSignals ;
5
6
6
7
export async function start ( ) {
7
8
if ( session ) {
@@ -11,25 +12,44 @@ export async function start() {
11
12
session . connect ( ) ;
12
13
await new Promise ( ( resolve ) => {
13
14
session . post ( "Profiler.enable" , ( ) => {
15
+ console . log ( `Recording CPU profile...` ) ;
14
16
session . post ( "Profiler.start" , ( ) => {
17
+ processSignals = registerSigHooks ( ) ;
15
18
resolve ( ) ;
16
19
} ) ;
17
20
} ) ;
18
21
} ) ;
19
22
}
20
23
21
24
async 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
+ } ) ;
25
38
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 ) ) ;
27
43
}
28
44
29
45
export async function stop ( ) {
30
46
if ( ! session ) {
31
47
return ;
32
48
}
49
+ if ( processSignals ) {
50
+ deregisterSigHooks ( processSignals ) ;
51
+ processSignals = null ;
52
+ }
33
53
const profile = await new Promise ( ( resolve ) => {
34
54
session . post ( "Profiler.stop" , ( err , { profile} ) => {
35
55
if ( err ) {
@@ -38,8 +58,38 @@ export async function stop() {
38
58
resolve ( profile ) ;
39
59
}
40
60
} ) ;
61
+ session = null ;
41
62
} ) ;
42
63
if ( profile ) {
43
64
await writeProfile ( profile ) ;
44
65
}
45
66
}
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