@@ -9,7 +9,7 @@ import * as logger from '../logger'
9
9
import { Timeout , CancellationError , waitUntil } from './timeoutUtils'
10
10
import { PollingSet } from './pollingSet'
11
11
import { getLogger } from '../logger/logger'
12
- import pidusage from 'pidusage '
12
+ import { isWin } from '../vscode/env '
13
13
14
14
export interface RunParameterContext {
15
15
/** Reports an error parsed from the stdin/stdout streams. */
@@ -67,14 +67,12 @@ export const eof = Symbol('EOF')
67
67
export interface ProcessStats {
68
68
memory : number
69
69
cpu : number
70
- elapsed : number
71
70
}
72
71
export class ChildProcessTracker {
73
72
static readonly pollingInterval : number = 10000
74
73
static readonly thresholds : ProcessStats = {
75
74
memory : 100 * 1024 * 1024 , // 100 MB
76
75
cpu : 50 ,
77
- elapsed : 30 * 1000 , // 30 seconds
78
76
}
79
77
static readonly logger = getLogger ( 'childProcess' )
80
78
#processByPid: Map < number , ChildProcess > = new Map < number , ChildProcess > ( )
@@ -118,11 +116,6 @@ export class ChildProcessTracker {
118
116
if ( stats . cpu > ChildProcessTracker . thresholds . cpu ) {
119
117
ChildProcessTracker . logger . warn ( `ChildProcess: Process ${ pid } exceeded cpu threshold: ${ stats . cpu } ` )
120
118
}
121
- if ( stats . elapsed > ChildProcessTracker . thresholds . elapsed ) {
122
- ChildProcessTracker . logger . warn (
123
- `ChildProcess: Process ${ pid } exceeded time threshold: ${ stats . elapsed } `
124
- )
125
- }
126
119
}
127
120
}
128
121
@@ -154,11 +147,47 @@ export class ChildProcessTracker {
154
147
}
155
148
156
149
public async getUsage ( pid : number ) : Promise < ProcessStats > {
157
- const stats = await pidusage ( pid )
158
- return {
159
- memory : stats . memory ,
160
- cpu : stats . cpu ,
161
- elapsed : stats . elapsed ,
150
+ const getWindowsUsage = ( ) => {
151
+ const cpuOutput = proc
152
+ . execFileSync ( 'wmic' , [
153
+ 'path' ,
154
+ 'Win32_PerfFormattedData_PerfProc_Process' ,
155
+ 'where' ,
156
+ `IDProcess=${ pid } ` ,
157
+ 'get' ,
158
+ 'PercentProcessorTime' ,
159
+ ] )
160
+ . toString ( )
161
+ const memOutput = proc
162
+ . execFileSync ( 'wmic' , [ 'process' , 'where' , `ProcessId=${ pid } ` , 'get' , 'WorkingSetSize' ] )
163
+ . toString ( )
164
+
165
+ const cpuPercentage = parseFloat ( cpuOutput . split ( '\n' ) [ 1 ] )
166
+ const memoryBytes = parseInt ( memOutput . split ( '\n' ) [ 1 ] ) * 1024
167
+
168
+ return {
169
+ cpu : isNaN ( cpuPercentage ) ? 0 : cpuPercentage ,
170
+ memory : memoryBytes ,
171
+ }
172
+ }
173
+ const getUnixUsage = ( ) => {
174
+ const cpuMemOutput = proc . execFileSync ( 'ps' , [ '-p' , pid . toString ( ) , '-o' , '%cpu,%mem' ] ) . toString ( )
175
+ const rssOutput = proc . execFileSync ( 'ps' , [ '-p' , pid . toString ( ) , '-o' , 'rss' ] ) . toString ( )
176
+
177
+ const cpuMemLines = cpuMemOutput . split ( '\n' ) [ 1 ] . trim ( ) . split ( / \s + / )
178
+ const cpuPercentage = parseFloat ( cpuMemLines [ 0 ] )
179
+ const memoryBytes = parseInt ( rssOutput . split ( '\n' ) [ 1 ] ) * 1024
180
+
181
+ return {
182
+ cpu : isNaN ( cpuPercentage ) ? 0 : cpuPercentage ,
183
+ memory : memoryBytes ,
184
+ }
185
+ }
186
+ try {
187
+ return isWin ( ) ? getWindowsUsage ( ) : getUnixUsage ( )
188
+ } catch ( e ) {
189
+ ChildProcessTracker . logger . warn ( `ChildProcess: Failed to get process stats for ${ pid } : ${ e } ` )
190
+ return { cpu : 0 , memory : 0 }
162
191
}
163
192
}
164
193
}
0 commit comments