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

Commit

Permalink
Add autoStart option
Browse files Browse the repository at this point in the history
  * When set will start maxConcurrentWorkers number of workers
  * Defaults to false
  * Added test and updated Readme
Defaults to false
  • Loading branch information
amasad committed Feb 4, 2015
1 parent 83e8c76 commit d5b3734
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 1 deletion.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ If you don't provide an `options` object then the following defaults will be use
, maxConcurrentCalls : Infinity
, maxCallTime : Infinity
, maxRetries : Infinity
, autoStart : false
}
```

Expand All @@ -124,6 +125,8 @@ If you don't provide an `options` object then the following defaults will be use

* **<code>maxRetries</code>** 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.

* **<code>autoStart</code>** 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.

### workerFarm.end(farm)

Child processes stay alive waiting for jobs indefinitely and your farm manager will stay alive managing its workers, so if you need it to stop then you have to do so explicitly. If you send your farm API to `workerFarm.end()` then it'll cleanly end your worker processes. Note though that it's a *soft* ending so it'll wait for child processes to finish what they are working on before asking them to die.
Expand Down
6 changes: 6 additions & 0 deletions lib/farm.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const DEFAULT_OPTIONS = {
, maxCallTime : Infinity // exceed this and the whole worker is terminated
, maxRetries : Infinity
, forcedKillTime : 100
, autoStart : false
}

const extend = require('xtend')
Expand Down Expand Up @@ -57,6 +58,11 @@ Farm.prototype.setup = function (methods) {
this.activeChildren = 0
this.callQueue = []

if (this.options.autoStart) {
while (this.activeChildren < this.options.maxConcurrentWorkers)
this.startChild()
}

return iface
}

Expand Down
7 changes: 6 additions & 1 deletion tests/child.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@ module.exports.stubborn = function (path, callback) {
fs.writeFileSync(path, String(retry + 1))
process.exit(-1)
}
}
}

var started = Date.now()
module.exports.uptime = function(callback) {
callback(null, Date.now() - started)
}
20 changes: 20 additions & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,26 @@ tape('many workers', function (t) {
})
})

tape('auto start workers', function (t) {
t.plan(4)

var child = workerFarm({ maxConcurrentWorkers: 3, autoStart: true }, childPath, ['uptime'])
, pids = []
, i = 3
, delay = 150

setTimeout(function() {
while (i--)
child.uptime(function (err, uptime) {
t.ok(uptime > 10, 'child has been up before the request')
})

workerFarm.end(child, function () {
t.ok(true, 'workerFarm ended')
})
}, delay)
})

// use the returned pids to check that we're using a child process per
// call when we set maxCallsPerWorker = 1 even when we have maxConcurrentWorkers = 1
tape('single call per worker', function (t) {
Expand Down

0 comments on commit d5b3734

Please sign in to comment.