Skip to content
This repository has been archived by the owner on Jun 29, 2022. It is now read-only.

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Jan 21, 2017
1 parent b97af03 commit 18beae6
Show file tree
Hide file tree
Showing 17 changed files with 362 additions and 178 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
language: node_js
node_js:
- "stable"
- "5"
- "6"
- "4"
- "0.12"
- "0.10"
File renamed without changes.
56 changes: 56 additions & 0 deletions bin/cli/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env node

'use strict'

const pkg = require('../../package.json')
require('update-notifier')({pkg}).notify()
const debug = require('debug')(pkg.name)

const workerFarm = require('worker-farm')
const range = require('lodash.range')
const minimist = require('minimist')
const series = require('run-series')
const path = require('path')

const getNumWorkers = require('../get-num-workers')
const getWorkerArgs = require('../get-worker-args')
const getFarmArgs = require('../get-farm-args')
const parseArgs = require('../parse-args')

const processArgv = process.argv.slice(2)
const argv = parseArgs(processArgv)
const cli = getFarmArgs(argv.farm)

const [filename] = cli.input
if (!filename) cli.showHelp()

const {file: fileOpts} = argv
const {flags: farmOpts} = cli
const {delayBetweenWorkers} = farmOpts
const numWorkers = getNumWorkers(farmOpts)
const workersRange = range(numWorkers)

const spawnWorkers = workersRange.map(function (worker) {
const workerArgs = getWorkerArgs(fileOpts, worker)
return spawnWorkerDelay(workerArgs, delayBetweenWorkers)
})

function spawnWorkerDelay (args, delay) {
function spawnWorker (cb) {
const parsedArgs = minimist(args)
debug('spawning', parsedArgs)
farm(parsedArgs, process.exit)
setTimeout(cb, delay)
}

return spawnWorker
}

const filePath = path.resolve(filename)
const farm = workerFarm(farmOpts, filePath)

debug('starting')
series(spawnWorkers, function () {
workerFarm.end(farm)
debug('finished')
})
41 changes: 0 additions & 41 deletions bin/config.js

This file was deleted.

9 changes: 9 additions & 0 deletions bin/get-farm-args/alias.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict'

module.exports = {
d: 'delayBetweenWorkers',
n: 'maxConcurrentWorkers',
w: 'maxConcurrentCallsPerWorker',
r: 'maxRetries',
autostart: 'autoStart'
}
105 changes: 105 additions & 0 deletions bin/get-farm-args/default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
'use strict'

module.exports = {

/**
* Allows you to control the lifespan of your child processes.
*
* A positive number will indicate that you only want each
* child to accept that many calls before it is terminated.
*
* This may be useful if you need to control memory leaks
* or similar in child * processes.
*/
maxCallsPerWorker: Infinity,

/*
* Will set the number of child processes to maintain concurrently.
*
* By default it is set to the number of CPUs available on
* the current system, but it can be any reasonable number,
* including 1.
*/
maxConcurrentWorkers: require('os').cpus().length,

/*
* Allows you to control the concurrency of individual child processes.
*
* Calls are placed into a queue and farmed out to child processes
* according to the number of calls they are allowed to handle concurrently.
*
* By default it is set to 1. If your calls aren't I/O bound
* then it won't matter what value you use here as the individual
* workers won't be able to execute more than a single call at a time.
*/
maxConcurrentCallsPerWorker: 1,

/*
* Allows you to control the maximum number of calls in the queue—either
* actively being processed or waiting for a worker to be processed.
*
* By default it is set to Infinity, that indicates no limit.
*
* If you have conditions that may endlessly queue jobs and you need to
* set a limit then provide a >0 value and any calls that push the
* limit will return on their callback with a MaxConcurrentCallsError
* error (check err.type == 'MaxConcurrentCallsError').
*/
maxConcurrentCalls: Infinity,

/*
* Use with caution, understand what this does before you use it!
*
* When !== Infinity, will cap a time, in milliseconds, that any single
* call can take to execute in a worker.
*
* If this time limit is exceeded by just a single call then
* the worker running that call will be killed and any calls running
* on that worker will have their callbacks returned with a
* TimeoutError (check err.type == 'TimeoutError').
*
* If you are running with maxConcurrentCallsPerWorker value greater
* than 1 then all calls currently executing will fail and will be
* automatically resubmitted uless you've changed the maxRetries option.
*
* Use this if you have jobs that may potentially end in infinite
* loops that you can't programatically end with your child code.
*
* Preferably run this with a maxConcurrentCallsPerWorker so you don't
* interrupt other calls when you have a timeout.
*
* This timeout operates on a per-call basis but will
* interrupt a whole worker.
*/
maxCallTime: Infinity,

/*
* Allows you to control the max number of call requeues
* after worker termination (unexpected or timeout).
*
* By default this option is set to Infinity which means that
* each call of each terminated worker will always be auto requeued.
*
* When the number of retries exceeds maxRetries value, the job
* callback will be executed with a ProcessTerminatedError.
*
* Note that if you are running with finite maxCallTime and
* maxConcurrentCallsPerWorkers greater than 1 then any
* TimeoutError will increase the retries counter for each
* concurrent call of the terminated worker.
*/
maxRetries: Infinity,

/*
* When set to true will start the workers as early as possible.
*
* Use this when your workers have to do expensive initialization.
* That way they'll be ready when the first request comes through.
*/
autoStart: true,

/**
* Determine the delay before spawn a new worker
*/
delayBetweenWorkers: 1000
}
25 changes: 25 additions & 0 deletions bin/get-farm-args/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict'

const path = require('path')
const meow = require('meow')
const fs = require('fs')

const helpPath = path.resolve(__dirname, '../cli/help.txt')
const pkg = require('../../package.json')
const defaults = require('./default')
const alias = require('./alias')

function getFarmArgs (argv) {
const cli = meow({
argv,
pkg,
help: fs.readFileSync(helpPath, 'utf8')
}, {
alias
})

const flags = Object.assign({}, defaults, cli.flags)
return Object.assign({}, cli, {flags})
}

module.exports = getFarmArgs
7 changes: 7 additions & 0 deletions bin/get-num-workers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict'

function getNumWorkers (flags) {
return flags.maxConcurrentCallsPerWorker * flags.maxConcurrentWorkers
}

module.exports = getNumWorkers
10 changes: 10 additions & 0 deletions bin/get-worker-args/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict'

function getWorkerArgs (fileOpts, worker) {
const workerArgs = [`--worker=${worker}`]
if (worker === 0) workerArgs.push('--isMaster')
else workerArgs.push('--no-isMaster')
return fileOpts.concat(workerArgs)
}

module.exports = getWorkerArgs
112 changes: 0 additions & 112 deletions bin/index.js

This file was deleted.

Loading

0 comments on commit 18beae6

Please sign in to comment.