22
33/* global SharedArrayBuffer */
44
5- const { Object } = primordials ;
5+ const { Math , Object } = primordials ;
66
77const EventEmitter = require ( 'events' ) ;
88const assert = require ( 'internal/assert' ) ;
99const path = require ( 'path' ) ;
1010
11+ const errorCodes = require ( 'internal/errors' ) . codes ;
1112const {
1213ERR_WORKER_PATH ,
1314ERR_WORKER_UNSERIALIZABLE_ERROR ,
1415ERR_WORKER_UNSUPPORTED_EXTENSION ,
1516ERR_WORKER_INVALID_EXEC_ARGV ,
1617ERR_INVALID_ARG_TYPE ,
17- } = require ( 'internal/errors' ) . codes ;
18+ } = errorCodes ;
1819const { validateString } = require ( 'internal/validators' ) ;
1920const { getOptionValue } = require ( 'internal/options' ) ;
2021
@@ -37,8 +38,13 @@ const { pathToFileURL } = require('url');
3738const {
3839 ownsProcessState,
3940 isMainThread,
41+ resourceLimits : resourceLimitsRaw ,
4042 threadId,
4143Worker : WorkerImpl ,
44+ kMaxYoungGenerationSizeMb,
45+ kMaxOldGenerationSizeMb,
46+ kCodeRangeSizeMb,
47+ kTotalResourceLimitCount
4248} = internalBinding ( 'worker' ) ;
4349
4450const kHandle = Symbol ( 'kHandle' ) ;
@@ -102,7 +108,8 @@ class Worker extends EventEmitter {
102108
103109const url = options . eval ? null : pathToFileURL ( filename ) ;
104110// 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 ) ) ;
106113if ( this [ kHandle ] . invalidExecArgv ) {
107114throw new ERR_WORKER_INVALID_EXEC_ARGV ( this [ kHandle ] . invalidExecArgv ) ;
108115}
@@ -113,7 +120,7 @@ class Worker extends EventEmitter {
113120} else if ( env !== undefined ) {
114121this [ kHandle ] . setEnvVars ( env ) ;
115122}
116- this [ kHandle ] . onexit = ( code ) => this [ kOnExit ] ( code ) ;
123+ this [ kHandle ] . onexit = ( code , customErr ) => this [ kOnExit ] ( code , customErr ) ;
117124this [ kPort ] = this [ kHandle ] . messagePort ;
118125this [ kPort ] . on ( 'message' , ( data ) => this [ kOnMessage ] ( data ) ) ;
119126this [ kPort ] . start ( ) ;
@@ -157,11 +164,15 @@ class Worker extends EventEmitter {
157164this [ kHandle ] . startThread ( ) ;
158165}
159166
160- [ kOnExit ] ( code ) {
167+ [ kOnExit ] ( code , customErr ) {
161168debug ( `[${ threadId } ] hears end event for Worker ${ this . threadId } ` ) ;
162169drainMessagePort ( this [ kPublicPort ] ) ;
163170drainMessagePort ( this [ kPort ] ) ;
164171this [ kDispose ] ( ) ;
172+ if ( customErr ) {
173+ debug ( `[${ threadId } ] failing with custom error ${ customErr } ` ) ;
174+ this . emit ( 'error' , new errorCodes [ customErr ] ( ) ) ;
175+ }
165176this . emit ( 'exit' , code ) ;
166177this . removeAllListeners ( ) ;
167178}
@@ -280,6 +291,12 @@ class Worker extends EventEmitter {
280291get stderr ( ) {
281292return this [ kParentSideStdio ] . stderr ;
282293}
294+
295+ get resourceLimits ( ) {
296+ if ( this [ kHandle ] === null ) return { } ;
297+
298+ return makeResourceLimits ( this [ kHandle ] . getResourceLimits ( ) ) ;
299+ }
283300}
284301
285302function pipeWithoutWarning ( source , dest ) {
@@ -294,10 +311,35 @@ function pipeWithoutWarning(source, dest) {
294311dest . _maxListeners = destMaxListeners ;
295312}
296313
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+
297337module . exports = {
298338 ownsProcessState,
299339 isMainThread,
300340SHARE_ENV ,
341+ resourceLimits :
342+ ! isMainThread ? makeResourceLimits ( resourceLimitsRaw ) : { } ,
301343 threadId,
302344 Worker,
303345} ;
0 commit comments