@stdlib/utils-parallel 0.0.7 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../lib/defaults.js", "../lib/validate.js", "../lib/node/env.js", "../lib/node/options.js", "../lib/node/exec.js", "../lib/node/index.js", "../lib/main.js", "../lib/index.js"],
4
+ "sourcesContent": ["/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar numCPUs = require( '@stdlib/os-num-cpus' );\n\n\n// MAIN //\n\n/**\n* Returns default options.\n*\n* @private\n* @returns {Object} default options\n*\n* @example\n* var o = defaults();\n* // returns {...}\n*/\nfunction defaults() {\n\treturn {\n\t\t// Number of workers:\n\t\t'workers': numCPUs - 1,\n\n\t\t// Number of scripts to execute concurrently:\n\t\t'concurrency': numCPUs - 1,\n\n\t\t// Executable file/command:\n\t\t'cmd': 'node',\n\n\t\t// Boolean indicating whether script output can be interleaved or must be ordered:\n\t\t'ordered': false,\n\n\t\t// Process user identity:\n\t\t'uid': null,\n\n\t\t// Process group identity:\n\t\t'gid': null,\n\n\t\t// `stdio` encoding:\n\t\t'encoding': 'buffer',\n\n\t\t// Max child process `stdio` buffer size:\n\t\t'maxBuffer': 200 * 1024 * 1024 // bytes\n\t};\n}\n\n\n// EXPORTS //\n\nmodule.exports = defaults;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar isObject = require( '@stdlib/assert-is-plain-object' );\nvar hasOwnProp = require( '@stdlib/assert-has-own-property' );\nvar isPositiveInteger = require( '@stdlib/assert-is-positive-integer' ).isPrimitive;\nvar isNonNegativeInteger = require( '@stdlib/assert-is-nonnegative-integer' ).isPrimitive;\nvar isBoolean = require( '@stdlib/assert-is-boolean' ).isPrimitive;\nvar isString = require( '@stdlib/assert-is-string' ).isPrimitive;\nvar format = require( '@stdlib/string-format' );\n\n\n// MAIN //\n\n/**\n* Validates function options.\n*\n* @private\n* @param {Object} opts - destination object\n* @param {Options} options - options to validate\n* @param {string} [options.cmd] - executable file/command\n* @param {PositiveInteger} [options.concurrency] - number of scripts to execute concurrently\n* @param {PositiveInteger} [options.workers] - number of workers\n* @param {boolean} [options.ordered] - boolean indicating whether to preserve the order of script output\n* @param {NonNegativeInteger} [options.uid] - process user identity\n* @param {NonNegativeInteger} [options.gid] - process group identity\n* @param {NonNegativeInteger} [options.maxBuffer] - max child process `stdio` buffer size\n* @returns {(Error|null)} error or null\n*\n* @example\n* var opts = {};\n* var options = {\n* 'concurrency': 4,\n* 'workers': 2\n* };\n* var err = validate( opts, options );\n* if ( err ) {\n* throw err;\n* }\n*/\nfunction validate( opts, options ) {\n\tif ( !isObject( options ) ) {\n\t\treturn new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) );\n\t}\n\tif ( hasOwnProp( options, 'concurrency' ) ) {\n\t\topts.concurrency = options.concurrency;\n\t\tif ( !isPositiveInteger( opts.concurrency ) ) {\n\t\t\treturn new TypeError( format( 'invalid option. `%s` option must be a positive integer. Option: `%s`.', 'concurrency', opts.concurrency ) );\n\t\t}\n\t}\n\tif ( hasOwnProp( options, 'workers' ) ) {\n\t\topts.workers = options.workers;\n\t\tif ( !isPositiveInteger( opts.workers ) ) {\n\t\t\treturn new TypeError( format( 'invalid option. `%s` option must be a positive integer. Option: `%s`.', 'workers', opts.workers ) );\n\t\t}\n\t}\n\tif ( hasOwnProp( options, 'cmd' ) ) {\n\t\topts.cmd = options.cmd;\n\t\tif ( !isString( opts.cmd ) ) {\n\t\t\treturn new TypeError( format( 'invalid option. `%s` option must be a string. Option: `%s`.', 'cmd', opts.cmd ) );\n\t\t}\n\t}\n\tif ( hasOwnProp( options, 'ordered' ) ) {\n\t\topts.ordered = options.ordered;\n\t\tif ( !isBoolean( opts.ordered ) ) {\n\t\t\treturn new TypeError( format( 'invalid option. `%s` option must be a boolean. Option: `%s`.', 'ordered', opts.ordered ) );\n\t\t}\n\t}\n\tif ( hasOwnProp( options, 'uid' ) ) {\n\t\topts.uid = options.uid;\n\t\tif ( !isNonNegativeInteger( opts.uid ) ) {\n\t\t\treturn new TypeError( format( 'invalid option. `%s` option must be a nonnegative integer. Option: `%s`.', 'uid', opts.uid ) );\n\t\t}\n\t}\n\tif ( hasOwnProp( options, 'gid' ) ) {\n\t\topts.gid = options.gid;\n\t\tif ( !isNonNegativeInteger( opts.gid ) ) {\n\t\t\treturn new TypeError( format( 'invalid option. `%s` option must be a nonnegative integer. Option: `%s`.', 'gid', opts.gid ) );\n\t\t}\n\t}\n\tif ( hasOwnProp( options, 'maxBuffer' ) ) {\n\t\topts.maxBuffer = options.maxBuffer;\n\t\tif ( !isNonNegativeInteger( opts.maxBuffer ) ) {\n\t\t\treturn new TypeError( format( 'invalid option. `%s` option must be a nonnegative integer. Option: `%s`.', 'maxBuffer', opts.maxBuffer ) );\n\t\t}\n\t}\n\treturn null;\n}\n\n\n// EXPORTS //\n\nmodule.exports = validate;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar objectKeys = require( '@stdlib/utils-keys' );\nvar ENV = require( '@stdlib/process-env' );\n\n\n// FUNCTIONS //\n\n/**\n* Copies `process.env`.\n*\n* ## Notes\n*\n* - This implementation accommodates `process.env` on older Node.js versions (<=v0.10.x), where `process.env` was object-like, but would show unexpected behavior when attempting to get own property descriptors.\n*\n* @private\n* @returns {Object} copy of `process.env`\n*/\nfunction copy() {\n\tvar keys;\n\tvar env;\n\tvar out;\n\tvar i;\n\n\tkeys = objectKeys( ENV );\n\tout = {};\n\tfor ( i = 0; i < keys.length; i++ ) {\n\t\tenv = keys[ i ];\n\t\tout[ env ] = ENV[ env ];\n\t}\n\treturn out;\n}\n\n\n// MAIN //\n\n/**\n* Returns worker environment variables.\n*\n* @private\n* @param {Options} opts - options\n* @param {string} opts.cmd - executable file/command\n* @param {boolean} opts.ordered - boolean indicating whether to preserve order of script output\n* @param {(NonNegativeInteger|null)} opts.uid - process user identity\n* @param {(NonNegativeInteger|null)} opts.gid - process group identity\n* @param {string} opts.encoding - `stdio` encoding\n* @param {NonNegativeInteger} opts.maxBuffer - max child process `stdio` buffer size\n* @returns {Object} environment variables\n*/\nfunction env( opts ) {\n\tvar out = copy();\n\n\tout.WORKER_CMD = opts.cmd;\n\tout.WORKER_ENCODING = opts.encoding;\n\tout.WORKER_MAX_BUFFER = opts.maxBuffer;\n\n\tif ( opts.ordered ) {\n\t\tout.WORKER_ORDERED = '1';\n\t}\n\tif ( opts.uid ) {\n\t\tout.WORKER_UID = opts.uid;\n\t}\n\tif ( opts.gid ) {\n\t\tout.WORKER_GID = opts.gid;\n\t}\n\treturn out;\n}\n\n\n// EXPORTS //\n\nmodule.exports = env;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar cwd = require( '@stdlib/process-cwd' );\nvar env = require( './env.js' );\n\n\n// MAIN //\n\n/**\n* Returns child process options.\n*\n* @private\n* @param {Options} options - worker options\n* @param {(NonNegativeInteger|null)} [options.uid] - process user identity\n* @param {(NonNegativeInteger|null)} [options.gid] - process group identity\n* @returns {Object} child process options\n*/\nfunction getOpts( options ) {\n\tvar opts = {\n\t\t'cwd': cwd(),\n\t\t'env': env( options ),\n\t\t'stdio': 'inherit' // Use stdio of parent process\n\t};\n\tif ( options.uid ) {\n\t\topts.uid = options.uid;\n\t}\n\tif ( options.gid ) {\n\t\topts.gid = options.gid;\n\t}\n\treturn opts;\n}\n\n\n// EXPORTS //\n\nmodule.exports = getOpts;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar fork = require( 'child_process' ).fork;\nvar path = require( 'path' );\nvar logger = require( 'debug' );\nvar objectKeys = require( '@stdlib/utils-keys' );\nvar format = require( '@stdlib/string-format' );\nvar getOpts = require( './options.js' );\n\n\n// VARIABLES //\n\nvar debug = logger( 'parallel:exec' );\nvar WORKER_FILEPATH = path.resolve( __dirname, './worker/index.js' );\n\n\n// MAIN //\n\n/**\n* Executes scripts in parallel.\n*\n* @private\n* @param {StringArray} files - script absolute file paths\n* @param {Options} opts - options\n* @param {PositiveInteger} opts.concurrency - number of scripts to execute concurrently\n* @param {PositiveInteger} opts.workers - number of workers\n* @param {string} opts.cmd - executable file/command\n* @param {boolean} opts.ordered - boolean indicating whether to preserve order of script output\n* @param {(NonNegativeInteger|null)} opts.uid - process user identity\n* @param {(NonNegativeInteger|null)} opts.gid - process group identity\n* @param {string} opts.encoding - `stdio` encoding\n* @param {NonNegativeInteger} opts.maxBuffer - max child process `stdio` buffer size\n* @param {Callback} clbk - callback to invoke after executing all scripts\n*/\nfunction exec( files, opts, clbk ) {\n\tvar numClosed;\n\tvar workers;\n\tvar pending;\n\tvar fopts;\n\tvar args;\n\tvar proc;\n\tvar pids;\n\tvar pid;\n\tvar idx;\n\tvar err;\n\tvar i;\n\n\tdebug( 'Options: %s.', JSON.stringify( opts ) );\n\tnumClosed = 0;\n\n\tdebug( 'Creating %d workers...', opts.workers );\n\tworkers = {};\n\targs = [];\n\tfopts = getOpts( opts );\n\tfor ( i = 0; i < opts.workers; i++ ) {\n\t\tdebug( 'Creating child process...' );\n\t\tproc = fork( WORKER_FILEPATH, args, fopts );\n\n\t\tproc.on( 'error', onError( proc ) );\n\t\tproc.on( 'close', onClose( proc ) );\n\t\tproc.on( 'exit', onExit( proc ) );\n\t\tproc.on( 'disconnect', onDisconnect( proc ) );\n\t\tproc.on( 'message', onMessage( proc ) );\n\n\t\tdebug( 'Child process created. pid: %d.', proc.pid );\n\t\tworkers[ proc.pid ] = proc;\n\t}\n\tpids = objectKeys( workers );\n\tdebug( '%d workers created.', pids.length );\n\n\tdebug( 'Running %d scripts concurrently...', opts.concurrency );\n\tpending = {};\n\tidx = -1;\n\tfor ( i = 0; i < opts.concurrency; i++ ) {\n\t\tpid = pids[ i%pids.length ];\n\t\tnext( workers[ pid ] ); // eslint-disable-line node/callback-return\n\t}\n\n\t/**\n\t* Instructs a child process to run the next script.\n\t*\n\t* @private\n\t* @param {Object} child - child process\n\t* @returns {void}\n\t*/\n\tfunction next( child ) {\n\t\tvar numPending;\n\t\tidx += 1;\n\t\tif ( idx >= files.length ) {\n\t\t\tnumPending = objectKeys( pending ).length;\n\t\t\tif ( numPending > 0 ) {\n\t\t\t\tdebug( '%d scripts are pending.', numPending );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebug( 'All scripts have finished.' );\n\t\t\treturn close();\n\t\t}\n\t\tdebug( 'Instructing child process to run script: %s. pid: %d.', files[ idx ], child.pid );\n\t\tchild.send( files[ idx ] );\n\t\tpending[ files[ idx ] ] = true;\n\n\t\tdebug( '%d of %d scripts have been processed.', idx, files.length );\n\t}\n\n\t/**\n\t* Returns a callback to be invoked upon receiving a message from a child process.\n\t*\n\t* @private\n\t* @param {Object} child - child process\n\t* @returns {Callback} callback\n\t*/\n\tfunction onMessage( child ) {\n\t\treturn listener;\n\n\t\t/**\n\t\t* Callback invoked upon receiving a message from a child process.\n\t\t*\n\t\t* @private\n\t\t* @param {string} filepath - script filepath\n\t\t*/\n\t\tfunction listener( filepath ) {\n\t\t\tdebug( 'Child process message: %s. pid: %d.', filepath, child.pid );\n\n\t\t\t// Remove the script from the listing of pending scripts:\n\t\t\tdelete pending[ filepath ];\n\n\t\t\t// Indicate that the child process is ready for its next task:\n\t\t\tnext( child );\n\t\t}\n\t}\n\n\t/**\n\t* Returns a callback to be invoked upon child process close.\n\t*\n\t* @private\n\t* @param {Object} child - child process\n\t* @returns {Callback} callback\n\t*/\n\tfunction onClose( child ) {\n\t\treturn listener;\n\n\t\t/**\n\t\t* Callback invoked upon child process close.\n\t\t*\n\t\t* @private\n\t\t* @param {(number|null)} code - exit code\n\t\t* @param {(string|null)} signal - termination signal\n\t\t*/\n\t\tfunction listener( code, signal ) {\n\t\t\tdebug( 'Child process closed. Code: %d. Signal: %s. pid: %d.', code, signal, child.pid );\n\t\t\tprocessExit( code, signal );\n\t\t\tchildClosed();\n\t\t}\n\t}\n\n\t/**\n\t* Callback invoked if a child closes.\n\t*\n\t* @private\n\t*/\n\tfunction childClosed() {\n\t\tnumClosed += 1;\n\t\tdebug( '%d of %d child processes have closed.', numClosed, opts.workers );\n\t\tif ( numClosed === opts.workers ) {\n\t\t\tdone(); // eslint-disable-line node/callback-return\n\t\t}\n\t}\n\n\t/**\n\t* Returns a callback to be invoked upon child process exit.\n\t*\n\t* @private\n\t* @param {Object} child - child process\n\t* @returns {Callback} callback\n\t*/\n\tfunction onExit( child ) {\n\t\treturn listener;\n\n\t\t/**\n\t\t* Callback invoked upon child process exit.\n\t\t*\n\t\t* @private\n\t\t* @param {(number|null)} code - exit code\n\t\t* @param {(string|null)} signal - termination signal\n\t\t*/\n\t\tfunction listener( code, signal ) {\n\t\t\tdebug( 'Child process exited. Code: %d. Signal: %s. pid: %d.', code, signal, child.pid );\n\t\t\tprocessExit( code, signal );\n\t\t}\n\t}\n\n\t/**\n\t* Closes all workers.\n\t*\n\t* @private\n\t* @param {Error} [error] - error object\n\t*/\n\tfunction close( error ) {\n\t\tvar pids;\n\t\tvar pid;\n\t\tvar i;\n\t\tif ( error && !err ) {\n\t\t\terr = error;\n\t\t}\n\t\tdebug( 'Instructing child processes to close...' );\n\t\tpids = objectKeys( workers );\n\t\tfor ( i = 0; i < pids.length; i++ ) {\n\t\t\tpid = pids[ i ];\n\t\t\tdebug( 'Instructing child process (pid: %d) to close...', pid );\n\t\t\tworkers[ pid ].send( 'close' );\n\t\t}\n\t}\n\n\t/**\n\t* Returns a callback to be invoked upon child process disconnect.\n\t*\n\t* @private\n\t* @param {Object} child - child process\n\t* @returns {Callback} callback\n\t*/\n\tfunction onDisconnect( child ) {\n\t\treturn listener;\n\n\t\t/**\n\t\t* Callback invoked upon child process disconnect.\n\t\t*\n\t\t* @private\n\t\t*/\n\t\tfunction listener() {\n\t\t\tdebug( 'Child process disconnected. pid: %d.', child.pid );\n\t\t}\n\t}\n\n\t/**\n\t* Returns a callback to be invoked upon encountering a child process error.\n\t*\n\t* @private\n\t* @param {Object} child - child process\n\t* @returns {Callback} callback\n\t*/\n\tfunction onError( child ) {\n\t\treturn listener;\n\n\t\t/**\n\t\t* Callback invoked upon a child process error.\n\t\t*\n\t\t* @private\n\t\t* @param {Error} error - error object\n\t\t*/\n\t\tfunction listener( error ) {\n\t\t\tdebug( 'Child process error: %s. pid: %d.', error.message, child.pid );\n\t\t\tclose( error );\n\t\t}\n\t}\n\n\t/**\n\t* Processes process exit values. If provided a non-zero exit code or termination signal, instructs the process to close.\n\t*\n\t* @private\n\t* @param {(number|null)} code - exit code\n\t* @param {(string|null)} signal - termination signal\n\t* @returns {void}\n\t*/\n\tfunction processExit( code, signal ) {\n\t\tvar error;\n\t\tif ( err ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( code !== null && code !== 0 ) {\n\t\t\terror = new Error( format( 'unexpected error. Child process failed with exit code: `%u`.', code ) );\n\t\t} else if ( signal !== null ) {\n\t\t\terror = new Error( format( 'unexpected error. Child process failed due to termination signal: `%s`.', signal ) );\n\t\t}\n\t\tif ( error ) {\n\t\t\terror.code = code;\n\t\t\terror.signal = signal;\n\t\t\treturn close( error );\n\t\t}\n\t}\n\n\t/**\n\t* Callback invoked once all tasks are finished.\n\t*\n\t* @private\n\t* @returns {void}\n\t*/\n\tfunction done() {\n\t\tif ( err ) {\n\t\t\treturn clbk( err );\n\t\t}\n\t\tclbk();\n\t}\n}\n\n\n// EXPORTS //\n\nmodule.exports = exec;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MAIN //\n\nvar exec = require( './exec.js' );\n\n\n// EXPORTS //\n\nmodule.exports = exec;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n// MODULES //\n\nvar path = require( 'path' );\nvar isStringArray = require( '@stdlib/assert-is-string-array' ).primitives;\nvar isFunction = require( '@stdlib/assert-is-function' );\nvar format = require( '@stdlib/string-format' );\nvar cwd = require( '@stdlib/process-cwd' );\nvar defaults = require( './defaults.js' );\nvar validate = require( './validate.js' );\nvar exec = require( './node' );\n\n\n// MAIN //\n\n/**\n* Executes scripts in parallel.\n*\n* @param {StringArray} files - script file paths\n* @param {Options} [options] - function options\n* @param {string} [options.cmd='node'] - executable file/command\n* @param {PositiveInteger} [options.concurrency] - number of scripts to execute concurrently\n* @param {PositiveInteger} [options.workers] - number of workers\n* @param {boolean} [options.ordered=false] - boolean indicating whether to preserve the order of script output\n* @param {NonNegativeInteger} [options.uid] - process user identity\n* @param {NonNegativeInteger} [options.gid] - process group identity\n* @param {NonNegativeInteger} [options.maxBuffer=200*1024*1024] - max child process `stdio` buffer size\n* @param {Callback} clbk - callback to invoke after executing all scripts\n* @throws {TypeError} first argument must be an array of strings\n* @throws {TypeError} options argument must be an object\n* @throws {TypeError} must provide valid options\n* @throws {TypeError} callback argument must be a function\n*\n* @example\n* var files = [ './a.js', './b.js ' ];\n*\n* var opts = {\n* 'workers': 3,\n* 'concurrency': 3\n* };\n*\n* function done( error ) {\n* if ( error ) {\n* throw error;\n* }\n* }\n*\n* parallel( files, opts, done );\n*/\nfunction parallel() {\n\tvar options;\n\tvar files;\n\tvar opts;\n\tvar clbk;\n\tvar err;\n\tvar dir;\n\tvar i;\n\n\tfiles = arguments[ 0 ];\n\tif ( !isStringArray( files ) ) {\n\t\tthrow new TypeError( format( 'invalid argument. First argument must be an array of strings. Value: `%s`.', files ) );\n\t}\n\tfiles = files.slice();\n\topts = defaults();\n\tif ( arguments.length > 2 ) {\n\t\toptions = arguments[ 1 ];\n\t\tclbk = arguments[ 2 ];\n\t\terr = validate( opts, options );\n\t\tif ( err ) {\n\t\t\tthrow err;\n\t\t}\n\t} else {\n\t\tclbk = arguments[ 1 ];\n\t}\n\tif ( !isFunction( clbk ) ) {\n\t\tthrow new TypeError( format( 'invalid argument. Callback argument must be a function. Value: `%s`.', clbk ) );\n\t}\n\t// Prevent the number of concurrent scripts exceeding the number of actual scripts to run.\n\tif ( opts.concurrency > files.length ) {\n\t\topts.concurrency = files.length;\n\t}\n\t// Prevent the number of workers exceeding the number of concurrent scripts (excess capacity), as some workers would never be allocated scripts to run and always be idle.\n\tif ( opts.workers > opts.concurrency ) {\n\t\topts.workers = opts.concurrency;\n\t}\n\t// Resolve any relative paths to absolute paths...\n\tdir = cwd();\n\tfor ( i = 0; i < files.length; i++ ) {\n\t\tfiles[ i ] = path.resolve( dir, files[ i ] );\n\t}\n\texec( files, opts, done );\n\n\t/**\n\t* Callback invoked after executing all scripts.\n\t*\n\t* @private\n\t* @param {Error} error - error object\n\t* @returns {void}\n\t*/\n\tfunction done( error ) {\n\t\tif ( error ) {\n\t\t\treturn clbk( error );\n\t\t}\n\t\tclbk();\n\t}\n}\n\n\n// EXPORTS //\n\nmodule.exports = parallel;\n", "/**\n* @license Apache-2.0\n*\n* Copyright (c) 2018 The Stdlib Authors.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n'use strict';\n\n/**\n* Execute scripts in parallel.\n*\n* @module @stdlib/utils-parallel\n*\n* @example\n* var parallel = require( '@stdlib/utils-parallel' );\n*\n* function done( error ) {\n* if ( error ) {\n* throw error;\n* }\n* }\n* var files = [ './a.js', './b.js' ];\n* parallel( files, done );\n*/\n\n// MODULES //\n\nvar main = require( './main.js' );\n\n\n// EXPORTS //\n\nmodule.exports = main;\n"],
5
+ "mappings": "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",
6
+ "names": ["require_defaults", "__commonJSMin", "exports", "module", "numCPUs", "defaults", "require_validate", "__commonJSMin", "exports", "module", "isObject", "hasOwnProp", "isPositiveInteger", "isNonNegativeInteger", "isBoolean", "isString", "format", "validate", "opts", "options", "require_env", "__commonJSMin", "exports", "module", "objectKeys", "ENV", "copy", "keys", "env", "out", "i", "opts", "require_options", "__commonJSMin", "exports", "module", "cwd", "env", "getOpts", "options", "opts", "require_exec", "__commonJSMin", "exports", "module", "fork", "path", "logger", "objectKeys", "format", "getOpts", "debug", "WORKER_FILEPATH", "exec", "files", "opts", "clbk", "numClosed", "workers", "pending", "fopts", "args", "proc", "pids", "pid", "idx", "err", "i", "onError", "onClose", "onExit", "onDisconnect", "onMessage", "next", "child", "numPending", "close", "listener", "filepath", "code", "signal", "processExit", "childClosed", "done", "error", "require_node", "__commonJSMin", "exports", "module", "exec", "require_main", "__commonJSMin", "exports", "module", "path", "isStringArray", "isFunction", "format", "cwd", "defaults", "validate", "exec", "parallel", "options", "files", "opts", "clbk", "err", "dir", "i", "done", "error", "main"]
7
+ }
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- // TypeScript Version: 2.0
19
+ // TypeScript Version: 4.1
20
20
 
21
21
  /**
22
22
  * Interface defining function options.
@@ -133,7 +133,7 @@ declare function parallel( files: Array<string>, clbk: Callback ): void;
133
133
  *
134
134
  * parallel( files, opts, done );
135
135
  */
136
- declare function parallel( files: Array<string>, options: Options, clbk: Callback ): void; // tslint-disable-line max-line-length
136
+ declare function parallel( files: Array<string>, options: Options, clbk: Callback ): void;
137
137
 
138
138
 
139
139
  // EXPORTS //
@@ -31,7 +31,7 @@
31
31
  */
32
32
  function runner() {
33
33
  // TODO: implementation
34
- throw new Error( 'not implemented. Please post an issue on the @stdlib/stdlib issue tracker if you would like this to be implemented.' );
34
+ throw new Error( 'not implemented. Please post an issue on the @stdlib/stdlib issue tracker if you would like this to be implemented. https://github.com/stdlib-js/stdlib/issues/new/choose' );
35
35
  }
36
36
 
37
37
 
package/lib/defaults.js CHANGED
@@ -25,31 +25,43 @@ var numCPUs = require( '@stdlib/os-num-cpus' );
25
25
 
26
26
  // MAIN //
27
27
 
28
- var defaults = {};
29
-
30
- // Number of workers:
31
- defaults.workers = numCPUs - 1;
28
+ /**
29
+ * Returns default options.
30
+ *
31
+ * @private
32
+ * @returns {Object} default options
33
+ *
34
+ * @example
35
+ * var o = defaults();
36
+ * // returns {...}
37
+ */
38
+ function defaults() {
39
+ return {
40
+ // Number of workers:
41
+ 'workers': numCPUs - 1,
32
42
 
33
- // Number of scripts to execute concurrently:
34
- defaults.concurrency = defaults.workers;
43
+ // Number of scripts to execute concurrently:
44
+ 'concurrency': numCPUs - 1,
35
45
 
36
- // Executable file/command:
37
- defaults.cmd = 'node';
46
+ // Executable file/command:
47
+ 'cmd': 'node',
38
48
 
39
- // Boolean indicating whether script output can be interleaved or must be ordered:
40
- defaults.ordered = false;
49
+ // Boolean indicating whether script output can be interleaved or must be ordered:
50
+ 'ordered': false,
41
51
 
42
- // Process user identity:
43
- defaults.uid = null;
52
+ // Process user identity:
53
+ 'uid': null,
44
54
 
45
- // Process group identity:
46
- defaults.gid = null;
55
+ // Process group identity:
56
+ 'gid': null,
47
57
 
48
- // `stdio` encoding:
49
- defaults.encoding = 'buffer';
58
+ // `stdio` encoding:
59
+ 'encoding': 'buffer',
50
60
 
51
- // Max child process `stdio` buffer size:
52
- defaults.maxBuffer = 200 * 1024 * 1024; // bytes
61
+ // Max child process `stdio` buffer size:
62
+ 'maxBuffer': 200 * 1024 * 1024 // bytes
63
+ };
64
+ }
53
65
 
54
66
 
55
67
  // EXPORTS //
package/lib/index.js CHANGED
@@ -37,9 +37,9 @@
37
37
 
38
38
  // MODULES //
39
39
 
40
- var parallel = require( './main.js' );
40
+ var main = require( './main.js' );
41
41
 
42
42
 
43
43
  // EXPORTS //
44
44
 
45
- module.exports = parallel;
45
+ module.exports = main;
package/lib/main.js CHANGED
@@ -23,8 +23,8 @@
23
23
  var path = require( 'path' );
24
24
  var isStringArray = require( '@stdlib/assert-is-string-array' ).primitives;
25
25
  var isFunction = require( '@stdlib/assert-is-function' );
26
+ var format = require( '@stdlib/string-format' );
26
27
  var cwd = require( '@stdlib/process-cwd' );
27
- var copy = require( '@stdlib/utils-copy' );
28
28
  var defaults = require( './defaults.js' );
29
29
  var validate = require( './validate.js' );
30
30
  var exec = require( './node' );
@@ -45,7 +45,7 @@ var exec = require( './node' );
45
45
  * @param {NonNegativeInteger} [options.gid] - process group identity
46
46
  * @param {NonNegativeInteger} [options.maxBuffer=200*1024*1024] - max child process `stdio` buffer size
47
47
  * @param {Callback} clbk - callback to invoke after executing all scripts
48
- * @throws {TypeError} first argument must be a string array
48
+ * @throws {TypeError} first argument must be an array of strings
49
49
  * @throws {TypeError} options argument must be an object
50
50
  * @throws {TypeError} must provide valid options
51
51
  * @throws {TypeError} callback argument must be a function
@@ -77,10 +77,10 @@ function parallel() {
77
77
 
78
78
  files = arguments[ 0 ];
79
79
  if ( !isStringArray( files ) ) {
80
- throw new TypeError( 'invalid argument. First argument must be an array of string primitives. Value: `' + files + '`.' );
80
+ throw new TypeError( format( 'invalid argument. First argument must be an array of strings. Value: `%s`.', files ) );
81
81
  }
82
82
  files = files.slice();
83
- opts = copy( defaults );
83
+ opts = defaults();
84
84
  if ( arguments.length > 2 ) {
85
85
  options = arguments[ 1 ];
86
86
  clbk = arguments[ 2 ];
@@ -92,7 +92,7 @@ function parallel() {
92
92
  clbk = arguments[ 1 ];
93
93
  }
94
94
  if ( !isFunction( clbk ) ) {
95
- throw new TypeError( 'invalid argument. Callback argument must be a function. Value: `' + clbk + '`.' );
95
+ throw new TypeError( format( 'invalid argument. Callback argument must be a function. Value: `%s`.', clbk ) );
96
96
  }
97
97
  // Prevent the number of concurrent scripts exceeding the number of actual scripts to run.
98
98
  if ( opts.concurrency > files.length ) {
package/lib/node/exec.js CHANGED
@@ -24,6 +24,7 @@ var fork = require( 'child_process' ).fork;
24
24
  var path = require( 'path' );
25
25
  var logger = require( 'debug' );
26
26
  var objectKeys = require( '@stdlib/utils-keys' );
27
+ var format = require( '@stdlib/string-format' );
27
28
  var getOpts = require( './options.js' );
28
29
 
29
30
 
@@ -286,9 +287,9 @@ function exec( files, opts, clbk ) {
286
287
  return;
287
288
  }
288
289
  if ( code !== null && code !== 0 ) {
289
- error = new Error( 'Child process failed with exit code: '+code+'.' );
290
+ error = new Error( format( 'unexpected error. Child process failed with exit code: `%u`.', code ) );
290
291
  } else if ( signal !== null ) {
291
- error = new Error( 'Child process failed due to termination signal: '+signal+'.' );
292
+ error = new Error( format( 'unexpected error. Child process failed due to termination signal: `%s`.', signal ) );
292
293
  }
293
294
  if ( error ) {
294
295
  error.code = code;
@@ -56,7 +56,7 @@ function onMessage( message ) {
56
56
  debug( 'Environment configuration allows interleaved script output.' );
57
57
  child = spawn( proc.env.WORKER_CMD, message, done );
58
58
  }
59
- db[ child.pid ] = true;
59
+ db[ child.pid ] = child;
60
60
  }
61
61
 
62
62
  /**
package/lib/validate.js CHANGED
@@ -26,6 +26,7 @@ var isPositiveInteger = require( '@stdlib/assert-is-positive-integer' ).isPrimit
26
26
  var isNonNegativeInteger = require( '@stdlib/assert-is-nonnegative-integer' ).isPrimitive;
27
27
  var isBoolean = require( '@stdlib/assert-is-boolean' ).isPrimitive;
28
28
  var isString = require( '@stdlib/assert-is-string' ).isPrimitive;
29
+ var format = require( '@stdlib/string-format' );
29
30
 
30
31
 
31
32
  // MAIN //
@@ -58,48 +59,48 @@ var isString = require( '@stdlib/assert-is-string' ).isPrimitive;
58
59
  */
59
60
  function validate( opts, options ) {
60
61
  if ( !isObject( options ) ) {
61
- return new TypeError( 'invalid argument. Options argument must be an object. Value: `' + options + '`.' );
62
+ return new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) );
62
63
  }
63
64
  if ( hasOwnProp( options, 'concurrency' ) ) {
64
65
  opts.concurrency = options.concurrency;
65
66
  if ( !isPositiveInteger( opts.concurrency ) ) {
66
- return new TypeError( 'invalid option. `concurrency` option must be a positive integer. Option: `' + opts.concurrency + '`.' );
67
+ return new TypeError( format( 'invalid option. `%s` option must be a positive integer. Option: `%s`.', 'concurrency', opts.concurrency ) );
67
68
  }
68
69
  }
69
70
  if ( hasOwnProp( options, 'workers' ) ) {
70
71
  opts.workers = options.workers;
71
72
  if ( !isPositiveInteger( opts.workers ) ) {
72
- return new TypeError( 'invalid option. `workers` option must be a positive integer. Option: `' + opts.workers + '`.' );
73
+ return new TypeError( format( 'invalid option. `%s` option must be a positive integer. Option: `%s`.', 'workers', opts.workers ) );
73
74
  }
74
75
  }
75
76
  if ( hasOwnProp( options, 'cmd' ) ) {
76
77
  opts.cmd = options.cmd;
77
78
  if ( !isString( opts.cmd ) ) {
78
- return new TypeError( 'invalid option. `cmd` option must be a primitive string. Option: `' + opts.cmd + '`.' );
79
+ return new TypeError( format( 'invalid option. `%s` option must be a string. Option: `%s`.', 'cmd', opts.cmd ) );
79
80
  }
80
81
  }
81
82
  if ( hasOwnProp( options, 'ordered' ) ) {
82
83
  opts.ordered = options.ordered;
83
84
  if ( !isBoolean( opts.ordered ) ) {
84
- return new TypeError( 'invalid option. `ordered` option must be a primitive boolean. Option: `' + opts.ordered + '`.' );
85
+ return new TypeError( format( 'invalid option. `%s` option must be a boolean. Option: `%s`.', 'ordered', opts.ordered ) );
85
86
  }
86
87
  }
87
88
  if ( hasOwnProp( options, 'uid' ) ) {
88
89
  opts.uid = options.uid;
89
90
  if ( !isNonNegativeInteger( opts.uid ) ) {
90
- return new TypeError( 'invalid option. `uid` option must be a nonnegative integer. Option: `' + opts.uid + '`.' );
91
+ return new TypeError( format( 'invalid option. `%s` option must be a nonnegative integer. Option: `%s`.', 'uid', opts.uid ) );
91
92
  }
92
93
  }
93
94
  if ( hasOwnProp( options, 'gid' ) ) {
94
95
  opts.gid = options.gid;
95
96
  if ( !isNonNegativeInteger( opts.gid ) ) {
96
- return new TypeError( 'invalid option. `gid` option must be a nonnegative integer. Option: `' + opts.gid + '`.' );
97
+ return new TypeError( format( 'invalid option. `%s` option must be a nonnegative integer. Option: `%s`.', 'gid', opts.gid ) );
97
98
  }
98
99
  }
99
100
  if ( hasOwnProp( options, 'maxBuffer' ) ) {
100
101
  opts.maxBuffer = options.maxBuffer;
101
102
  if ( !isNonNegativeInteger( opts.maxBuffer ) ) {
102
- return new TypeError( 'invalid option. `maxBuffer` option must be a nonnegative integer. Option: `' + opts.maxBuffer + '`.' );
103
+ return new TypeError( format( 'invalid option. `%s` option must be a nonnegative integer. Option: `%s`.', 'maxBuffer', opts.maxBuffer ) );
103
104
  }
104
105
  }
105
106
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stdlib/utils-parallel",
3
- "version": "0.0.7",
3
+ "version": "0.2.1",
4
4
  "description": "Execute scripts in parallel.",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
@@ -13,9 +13,6 @@
13
13
  "url": "https://github.com/stdlib-js/stdlib/graphs/contributors"
14
14
  }
15
15
  ],
16
- "bin": {
17
- "parallel": "./bin/cli"
18
- },
19
16
  "main": "./lib",
20
17
  "browser": {
21
18
  "./lib": "./lib/browser/index.js",
@@ -42,33 +39,26 @@
42
39
  "url": "https://github.com/stdlib-js/stdlib/issues"
43
40
  },
44
41
  "dependencies": {
45
- "@stdlib/assert-has-own-property": "^0.0.x",
46
- "@stdlib/assert-is-boolean": "^0.0.x",
47
- "@stdlib/assert-is-function": "^0.0.x",
48
- "@stdlib/assert-is-nonnegative-integer": "^0.0.x",
49
- "@stdlib/assert-is-plain-object": "^0.0.x",
50
- "@stdlib/assert-is-positive-integer": "^0.0.x",
51
- "@stdlib/assert-is-string": "^0.0.x",
52
- "@stdlib/assert-is-string-array": "^0.0.x",
53
- "@stdlib/cli-ctor": "^0.0.x",
54
- "@stdlib/fs-read-file": "^0.0.x",
55
- "@stdlib/os-num-cpus": "^0.0.x",
56
- "@stdlib/process-cwd": "^0.0.x",
57
- "@stdlib/process-env": "^0.0.x",
58
- "@stdlib/utils-copy": "^0.0.x",
59
- "@stdlib/utils-keys": "^0.0.x",
42
+ "@stdlib/assert-has-own-property": "^0.1.1",
43
+ "@stdlib/assert-is-boolean": "^0.1.1",
44
+ "@stdlib/assert-is-function": "^0.1.1",
45
+ "@stdlib/assert-is-nonnegative-integer": "^0.1.0",
46
+ "@stdlib/assert-is-plain-object": "^0.1.1",
47
+ "@stdlib/assert-is-positive-integer": "^0.1.0",
48
+ "@stdlib/assert-is-string": "^0.1.1",
49
+ "@stdlib/assert-is-string-array": "^0.1.1",
50
+ "@stdlib/os-num-cpus": "^0.1.1",
51
+ "@stdlib/process-cwd": "^0.1.1",
52
+ "@stdlib/process-env": "^0.1.1",
53
+ "@stdlib/string-format": "^0.1.1",
54
+ "@stdlib/utils-keys": "^0.1.0",
60
55
  "debug": "^2.6.9"
61
56
  },
62
57
  "devDependencies": {
63
- "@stdlib/fs-unlink": "^0.0.x",
64
- "@stdlib/fs-write-file": "^0.0.x",
65
- "@stdlib/random-base-minstd": "^0.0.x",
66
- "@stdlib/utils-next-tick": "^0.0.x",
67
- "@stdlib/utils-noop": "^0.0.x",
68
58
  "proxyquire": "^2.0.0",
69
59
  "tape": "git+https://github.com/kgryte/tape.git#fix/globby",
70
60
  "istanbul": "^0.4.1",
71
- "tap-spec": "5.x.x"
61
+ "tap-min": "git+https://github.com/Planeshifter/tap-min.git"
72
62
  },
73
63
  "engines": {
74
64
  "node": ">=0.10.0",
@@ -114,7 +104,7 @@
114
104
  ],
115
105
  "__stdlib__": {},
116
106
  "funding": {
117
- "type": "patreon",
118
- "url": "https://www.patreon.com/athan"
107
+ "type": "opencollective",
108
+ "url": "https://opencollective.com/stdlib"
119
109
  }
120
110
  }
package/bin/cli DELETED
@@ -1,105 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * @license Apache-2.0
5
- *
6
- * Copyright (c) 2018 The Stdlib Authors.
7
- *
8
- * Licensed under the Apache License, Version 2.0 (the "License");
9
- * you may not use this file except in compliance with the License.
10
- * You may obtain a copy of the License at
11
- *
12
- * http://www.apache.org/licenses/LICENSE-2.0
13
- *
14
- * Unless required by applicable law or agreed to in writing, software
15
- * distributed under the License is distributed on an "AS IS" BASIS,
16
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- * See the License for the specific language governing permissions and
18
- * limitations under the License.
19
- */
20
-
21
- 'use strict';
22
-
23
- // MODULES //
24
-
25
- var resolve = require( 'path' ).resolve;
26
- var readFileSync = require( '@stdlib/fs-read-file' ).sync;
27
- var CLI = require( '@stdlib/cli-ctor' );
28
- var parallel = require( './../lib' );
29
-
30
-
31
- // FUNCTIONS //
32
-
33
- /**
34
- * Callback invoked upon executing all scripts.
35
- *
36
- * @private
37
- * @param {Error} [error] - error object
38
- * @throws {Error} unexpected error
39
- */
40
- function done( error ) {
41
- if ( error ) {
42
- throw error;
43
- }
44
- }
45
-
46
-
47
- // MAIN //
48
-
49
- /**
50
- * Main execution sequence.
51
- *
52
- * @private
53
- */
54
- function main() {
55
- var flags;
56
- var args;
57
- var opts;
58
- var cli;
59
-
60
- // Create a command-line interface:
61
- cli = new CLI({
62
- 'pkg': require( './../package.json' ),
63
- 'options': require( './../etc/cli_opts.json' ),
64
- 'help': readFileSync( resolve( __dirname, '..', 'docs', 'usage.txt' ), {
65
- 'encoding': 'utf8'
66
- })
67
- });
68
-
69
- // Get any provided command-line options:
70
- flags = cli.flags();
71
- if ( flags.help || flags.version ) {
72
- return;
73
- }
74
-
75
- // Get any command-line arguments:
76
- args = cli.args();
77
-
78
- opts = {};
79
- if ( flags.cmd ) {
80
- opts.cmd = flags.cmd;
81
- }
82
- if ( flags.workers ) {
83
- opts.workers = parseInt( flags.workers, 10 );
84
- }
85
- if ( flags.concurrency ) {
86
- opts.concurrency = parseInt( flags.concurrency, 10 );
87
- }
88
- if ( flags.ordered ) {
89
- opts.ordered = flags.ordered;
90
- }
91
- if ( flags.uid ) {
92
- opts.uid = parseInt( flags.uid, 10 );
93
- }
94
- if ( flags.gid ) {
95
- opts.gid = parseInt( flags.gid, 10 );
96
- }
97
- if ( flags.maxbuffer ) {
98
- opts.maxBuffer = parseInt( flags.maxbuffer, 10 );
99
- }
100
-
101
- // Run main:
102
- parallel( args, opts, done );
103
- }
104
-
105
- main();
package/docs/repl.txt DELETED
@@ -1,68 +0,0 @@
1
-
2
- {{alias}}( files, [options,] clbk )
3
- Executes scripts in parallel.
4
-
5
- Relative file paths are resolved relative to the current working directory.
6
-
7
- Ordered script output does not imply that scripts are executed in order. To
8
- preserve script order, execute the scripts sequentially via some other
9
- means.
10
-
11
- Parameters
12
- ----------
13
- files: Array<string>
14
- Script file paths.
15
-
16
- options: Object (optional)
17
- Options.
18
-
19
- options.cmd: string (optional)
20
- Executable file/command. Default: `'node'`.
21
-
22
- options.concurrency: integer (optional)
23
- Number of scripts to execute concurrently. Script concurrency cannot
24
- exceed the number of scripts. By specifying a concurrency greater than
25
- the number of workers, a worker may be executing more than `1` script at
26
- any one time. While not likely to be advantageous for synchronous
27
- scripts, setting a higher concurrency may be advantageous for scripts
28
- performing asynchronous tasks. If the script concurrency is less than
29
- the number of workers, the number of workers is reduced to match the
30
- specified concurrency. Default: `options.workers`.
31
-
32
- options.workers: integer (optional)
33
- Number of workers. Default: number of CPUs minus `1`.
34
-
35
- options.ordered: boolean (optional)
36
- Boolean indicating whether to preserve the order of script output. By
37
- default, the `stdio` output for each script is interleaved; i.e., the
38
- `stdio` output from one script may be interleaved with the `stdio`
39
- output from one or more other scripts. To preserve the `stdio` output
40
- order for each script, set the `ordered` option to `true`. Default:
41
- `false`.
42
-
43
- options.uid: integer (optional)
44
- Process user identity.
45
-
46
- options.gid: integer (optional)
47
- Process group identity.
48
-
49
- options.maxBuffer: integer (optional)
50
- Max child process `stdio` buffer size. This option is only applied when
51
- `options.ordered = true`. Default: `200*1024*1024`.
52
-
53
- clbk: Function
54
- Callback to invoke after executing all scripts.
55
-
56
- Examples
57
- --------
58
- > function done( error ) { if ( error ) { throw error; } };
59
- > var files = [ './a.js', './b.js' ];
60
- > {{alias}}( files, done );
61
-
62
- // Specify the number of workers:
63
- > var opts = { 'workers': 8 };
64
- > {{alias}}( files, opts, done );
65
-
66
- See Also
67
- --------
68
-