2
2
3
3
/* global SharedArrayBuffer */
4
4
5
- const { Object } = primordials ;
5
+ const { Math , Object } = primordials ;
6
6
7
7
const EventEmitter = require ( 'events' ) ;
8
8
const assert = require ( 'internal/assert' ) ;
9
9
const path = require ( 'path' ) ;
10
10
11
+ const errorCodes = require ( 'internal/errors' ) . codes ;
11
12
const {
12
13
ERR_WORKER_PATH ,
13
14
ERR_WORKER_UNSERIALIZABLE_ERROR ,
14
15
ERR_WORKER_UNSUPPORTED_EXTENSION ,
15
16
ERR_WORKER_INVALID_EXEC_ARGV ,
16
17
ERR_INVALID_ARG_TYPE ,
17
- } = require ( 'internal/errors' ) . codes ;
18
+ } = errorCodes ;
18
19
const { validateString } = require ( 'internal/validators' ) ;
19
20
const { getOptionValue } = require ( 'internal/options' ) ;
20
21
@@ -37,8 +38,13 @@ const { pathToFileURL } = require('url');
37
38
const {
38
39
ownsProcessState,
39
40
isMainThread,
41
+ resourceLimits : resourceLimitsRaw ,
40
42
threadId,
41
43
Worker : WorkerImpl ,
44
+ kMaxYoungGenerationSizeMb,
45
+ kMaxOldGenerationSizeMb,
46
+ kCodeRangeSizeMb,
47
+ kTotalResourceLimitCount
42
48
} = internalBinding ( 'worker' ) ;
43
49
44
50
const kHandle = Symbol ( 'kHandle' ) ;
@@ -102,7 +108,8 @@ class Worker extends EventEmitter {
102
108
103
109
const url = options . eval ? null : pathToFileURL ( filename ) ;
104
110
// Set up the C++ handle for the worker, as well as some internal wiring.
105
- this [ kHandle ] = new WorkerImpl ( url , options . execArgv ) ;
111
+ this [ kHandle ] = new WorkerImpl ( url , options . execArgv ,
112
+ parseResourceLimits ( options . resourceLimits ) ) ;
106
113
if ( this [ kHandle ] . invalidExecArgv ) {
107
114
throw new ERR_WORKER_INVALID_EXEC_ARGV ( this [ kHandle ] . invalidExecArgv ) ;
108
115
}
@@ -113,7 +120,7 @@ class Worker extends EventEmitter {
113
120
} else if ( env !== undefined ) {
114
121
this [ kHandle ] . setEnvVars ( env ) ;
115
122
}
116
- this [ kHandle ] . onexit = ( code ) => this [ kOnExit ] ( code ) ;
123
+ this [ kHandle ] . onexit = ( code , customErr ) => this [ kOnExit ] ( code , customErr ) ;
117
124
this [ kPort ] = this [ kHandle ] . messagePort ;
118
125
this [ kPort ] . on ( 'message' , ( data ) => this [ kOnMessage ] ( data ) ) ;
119
126
this [ kPort ] . start ( ) ;
@@ -157,11 +164,15 @@ class Worker extends EventEmitter {
157
164
this [ kHandle ] . startThread ( ) ;
158
165
}
159
166
160
- [ kOnExit ] ( code ) {
167
+ [ kOnExit ] ( code , customErr ) {
161
168
debug ( `[${ threadId } ] hears end event for Worker ${ this . threadId } ` ) ;
162
169
drainMessagePort ( this [ kPublicPort ] ) ;
163
170
drainMessagePort ( this [ kPort ] ) ;
164
171
this [ kDispose ] ( ) ;
172
+ if ( customErr ) {
173
+ debug ( `[${ threadId } ] failing with custom error ${ customErr } ` ) ;
174
+ this . emit ( 'error' , new errorCodes [ customErr ] ( ) ) ;
175
+ }
165
176
this . emit ( 'exit' , code ) ;
166
177
this . removeAllListeners ( ) ;
167
178
}
@@ -280,6 +291,12 @@ class Worker extends EventEmitter {
280
291
get stderr ( ) {
281
292
return this [ kParentSideStdio ] . stderr ;
282
293
}
294
+
295
+ get resourceLimits ( ) {
296
+ if ( this [ kHandle ] === null ) return { } ;
297
+
298
+ return makeResourceLimits ( this [ kHandle ] . getResourceLimits ( ) ) ;
299
+ }
283
300
}
284
301
285
302
function pipeWithoutWarning ( source , dest ) {
@@ -294,10 +311,35 @@ function pipeWithoutWarning(source, dest) {
294
311
dest . _maxListeners = destMaxListeners ;
295
312
}
296
313
314
+ const resourceLimitsArray = new Float64Array ( kTotalResourceLimitCount ) ;
315
+ function parseResourceLimits ( obj ) {
316
+ const ret = resourceLimitsArray ;
317
+ ret . fill ( - 1 ) ;
318
+ if ( typeof obj !== 'object' || obj === null ) return ret ;
319
+
320
+ if ( typeof obj . maxOldGenerationSizeMb === 'number' )
321
+ ret [ kMaxOldGenerationSizeMb ] = Math . max ( obj . maxOldGenerationSizeMb , 2 ) ;
322
+ if ( typeof obj . maxYoungGenerationSizeMb === 'number' )
323
+ ret [ kMaxYoungGenerationSizeMb ] = obj . maxYoungGenerationSizeMb ;
324
+ if ( typeof obj . codeRangeSizeMb === 'number' )
325
+ ret [ kCodeRangeSizeMb ] = obj . codeRangeSizeMb ;
326
+ return ret ;
327
+ }
328
+
329
+ function makeResourceLimits ( float64arr ) {
330
+ return {
331
+ maxYoungGenerationSizeMb : float64arr [ kMaxYoungGenerationSizeMb ] ,
332
+ maxOldGenerationSizeMb : float64arr [ kMaxOldGenerationSizeMb ] ,
333
+ codeRangeSizeMb : float64arr [ kCodeRangeSizeMb ]
334
+ } ;
335
+ }
336
+
297
337
module . exports = {
298
338
ownsProcessState,
299
339
isMainThread,
300
340
SHARE_ENV ,
341
+ resourceLimits :
342
+ ! isMainThread ? makeResourceLimits ( resourceLimitsRaw ) : { } ,
301
343
threadId,
302
344
Worker,
303
345
} ;
0 commit comments