Skip to content

Instantly share code, notes, and snippets.

@HyphnKnight
Created October 31, 2016 15:46
Show Gist options
  • Select an option

  • Save HyphnKnight/fc60639e8f6a865b0e10d262daa2fc64 to your computer and use it in GitHub Desktop.

Select an option

Save HyphnKnight/fc60639e8f6a865b0e10d262daa2fc64 to your computer and use it in GitHub Desktop.
const
numberOfCPUs = require('os').cpus().length,
cluster = require('cluster');
let activeCPUS = 0;
function chunk( array, number ) {
const
result = [],
arrayLength = array.length;
for ( let index = 0; index < arrayLength; ++index ) {
if ( !result[ Math.floor( index / number ) ] ) {
result[ Math.floor( index / number ) ] = [];
}
result[ Math.floor( index / number ) ].push( array[ index ] );
}
return result;
}
function flatten( array ) {
return [].concat.apply( [], array );
}
function map( array, func = identity ) {
const
arrayLength = array.length,
result = [];
for ( let index = 0; index < arrayLength; ++index ) {
result[index] = func( array[ index ], index, array );
}
return result;
}
function times( length, func = identity ) {
return map( new Array( length ).fill( 0 ), ( _, i ) => func( i, length ) );
}
function thread( array, func ) {
const
usableCPUS = numberOfCPUs - activeCPUS,
chunkData = chunk( array, array.length / usableCPUS ),
chunks = chunkData.length;
if (cluster.isMaster) {
const workers = times( chunks, () => cluster.fork() );
return Promise.all(
workers.map( ( worker, i ) => createThread( worker, chunkData, i, func ) )
)
.then( results => flatten( results ) )
.catch( error => {
throw error;
} )
} else if ( cluster.isWorker ) {
let index = 0;
process.on('message', ( data ) => {
let results;
try {
results = map( data, data => func( data ) );
} catch ( error ) {
process.exit(1);
}
if ( !!results.then ) {
results.then( data => process.send( results, () => process.exit(0) ) )
} else {
process.send( results, () => process.exit(0) )
}
});
return { then: () => {} };
}
}
function createThread( worker, chunkData, index, func ) {
return new Promise( ( resolve, reject ) => {
worker.on( 'message', function workerTask( msg ) {
resolve( msg );
} );
worker.send( chunkData[ index ] );
} );
}
thread.isMaster = cluster.isMaster;
thread.isWorker = cluster.isWorker;
module.exports = thread;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment