diff --git a/README.md b/README.md index 72415bf..6e100bd 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ There are several options that you should be aware of when using forever. Most o 'uid': 'your-UID', // Custom uid for this forever process. (default: autogen) 'pidFile': 'path/to/a.pid', // Path to put pid information for the process(es) started 'max': 10, // Sets the maximum number of times a given script should run + 'cooldownInterval': 300, // Stop restarting if max is reached during this interval (in seconds) 'killTree': true, // Kills the entire child process tree on `exit` // diff --git a/lib/forever-monitor/monitor.js b/lib/forever-monitor/monitor.js index 02c75e6..391246b 100755 --- a/lib/forever-monitor/monitor.js +++ b/lib/forever-monitor/monitor.js @@ -35,6 +35,9 @@ var Monitor = exports.Monitor = function (script, options) { if (options.watch) { plugins.watch.attach.call(monitor, options); } + if (options.cooldownInterval) { + plugins.cooldown.attach.call(monitor, options); + } } var execPath = process.execPath, @@ -50,6 +53,7 @@ var Monitor = exports.Monitor = function (script, options) { this.id = options.id || false; this.pidFile = options.pidFile; this.max = options.max; + this.cooldownInterval = options.cooldownInterval || null; this.killTTL = options.killTTL; this.killSignal = options.killSignal || 'SIGKILL'; this.childExists = false; diff --git a/lib/forever-monitor/plugins/cooldown.js b/lib/forever-monitor/plugins/cooldown.js new file mode 100644 index 0000000..505c19c --- /dev/null +++ b/lib/forever-monitor/plugins/cooldown.js @@ -0,0 +1,28 @@ +/* + * watch.js: Plugin for `Monitor` instances which decreases the count of + * failures over time. It makes the max option time sensitive (ie it's not the + * same to have 10 failures in 10 seconds and 10 failures in 10 weeks). + * + * (C) 2010 Charlie Robbins & the Contributors + * MIT LICENCE + * + */ + +// +// Name the plugin +// +exports.name = 'cooldown'; + +// +// ### function attach (options) +// #### @options {Object} Options for attaching to `Monitor` +// +// Attaches functionality for logging stdout and stderr to `Monitor` instances. +// +exports.attach = function (options) { + var monitor = this; + + setInterval(function() { + monitor.times = Math.floor(monitor.times / 2); + }, options.cooldownInterval * 1000); +} diff --git a/lib/forever-monitor/plugins/index.js b/lib/forever-monitor/plugins/index.js index 24d3127..a2b5a26 100644 --- a/lib/forever-monitor/plugins/index.js +++ b/lib/forever-monitor/plugins/index.js @@ -6,5 +6,6 @@ * */ -exports.logger = require('./logger'); -exports.watch = require('./watch'); \ No newline at end of file +exports.logger = require('./logger'); +exports.watch = require('./watch'); +exports.cooldown = require('./cooldown') diff --git a/test/plugins/cooldown-test.js b/test/plugins/cooldown-test.js new file mode 100644 index 0000000..b81fc76 --- /dev/null +++ b/test/plugins/cooldown-test.js @@ -0,0 +1,43 @@ +var assert = require('assert') + path = require('path'), + vows = require('vows'), + fmonitor = require('../../lib'), + macros = require('../helpers/macros'); + +var examplesDir = path.join(__dirname, '..', '..', 'examples'); + +vows.describe('forever-monitor/plugins/logger').addBatch({ + 'When using the cooldown plugin': { + 'running error-on-timer sample one hundred times': { + topic: function () { + var script = path.join(examplesDir, 'error-on-timer.js'); + var options = { + max: 10, + cooldownInterval: 1, + silent: true, + outFile: 'test/fixtures/stdout.log', + errFile: 'test/fixtures/stderr.log', + args: [] + } + var child = new (fmonitor.Monitor)(script, options); + setTimeout(this.callback.bind({}, null, child), 2100); + child.start(); + }, + 'should have not reached max': function (err, child) { + assert.ok(child.times < 10); + } + }, + 'running error-on-timer sample three times': macros.assertTimes( + path.join(examplesDir, 'error-on-timer.js'), + 3, + { + cooldownInterval: 10, + minUptime: 200, + silent: true, + outFile: 'test/fixtures/stdout.log', + errFile: 'test/fixtures/stderr.log', + args: [] + } + ) + } +}).export(module);