@@ -7,6 +7,8 @@ import * as proc from 'child_process' // eslint-disable-line no-restricted-impor
7
7
import * as crossSpawn from 'cross-spawn'
8
8
import * as logger from '../logger'
9
9
import { Timeout , CancellationError , waitUntil } from './timeoutUtils'
10
+ import { PollingSet } from './pollingSet'
11
+ import { getLogger } from '../logger/logger'
10
12
11
13
export interface RunParameterContext {
12
14
/** Reports an error parsed from the stdin/stdout streams. */
@@ -61,14 +63,61 @@ export interface ChildProcessResult {
61
63
62
64
export const eof = Symbol ( 'EOF' )
63
65
66
+ export class ChildProcessTracker extends Map < number , ChildProcess > {
67
+ static pollingInterval : number = 5000
68
+ #processPoller: PollingSet < number >
69
+
70
+ public constructor ( ) {
71
+ super ( )
72
+ this . #processPoller = new PollingSet ( ChildProcessTracker . pollingInterval , ( ) => { } )
73
+ }
74
+
75
+ private cleanUpProcesses ( ) {
76
+ const terminatedProcesses = Array . from ( this . #processPoller. values ( ) ) . filter (
77
+ ( pid : number ) => ! this . has ( pid ) || this . get ( pid ) ?. stopped
78
+ )
79
+ for ( const pid of terminatedProcesses ) {
80
+ this . #processPoller. delete ( pid )
81
+ }
82
+ }
83
+
84
+ public monitorProcesses ( ) {
85
+ this . cleanUpProcesses ( )
86
+ getLogger ( ) . debug ( `Active running processes size: ${ this . #processPoller. size } ` )
87
+
88
+ for ( const pid of this . #processPoller. values ( ) ) {
89
+ const process = this . get ( pid )
90
+ if ( process ) {
91
+ getLogger ( ) . debug ( `Active running process: ${ process . toString ( ) } ` )
92
+ }
93
+ }
94
+ }
95
+
96
+ public override set ( key : number , value : ChildProcess ) : this {
97
+ this . #processPoller. add ( key )
98
+ super . set ( key , value )
99
+ return this
100
+ }
101
+
102
+ public override delete ( key : number ) : boolean {
103
+ this . #processPoller. delete ( key )
104
+ return super . delete ( key )
105
+ }
106
+
107
+ public override clear ( ) : void {
108
+ this . #processPoller. clear ( )
109
+ super . clear ( )
110
+ }
111
+ }
112
+
64
113
/**
65
114
* Convenience class to manage a child process
66
115
* To use:
67
116
* - instantiate
68
117
* - call and await run to get the results (pass or fail)
69
118
*/
70
119
export class ChildProcess {
71
- static #runningProcesses: Map < number , ChildProcess > = new Map ( )
120
+ static #runningProcesses: ChildProcessTracker = new ChildProcessTracker ( )
72
121
#childProcess: proc . ChildProcess | undefined
73
122
#processErrors: Error [ ] = [ ]
74
123
#processResult: ChildProcessResult | undefined
0 commit comments