From 7aa72c99e1de6f8dc1c5bfdd57927651d72a3fd7 Mon Sep 17 00:00:00 2001 From: indexzero Date: Mon, 2 Jan 2012 22:36:01 -0500 Subject: [PATCH] [api test doc] Expose `.fork()` through forever for node-specific processes. Currently blocked by joyent/node#2454 --- examples/process-send.js | 6 ++++++ lib/forever/monitor.js | 21 ++++++++++++++++++++- test/fork-test.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 examples/process-send.js create mode 100644 test/fork-test.js diff --git a/examples/process-send.js b/examples/process-send.js new file mode 100644 index 00000000..220f3cb7 --- /dev/null +++ b/examples/process-send.js @@ -0,0 +1,6 @@ + +setInterval(function () { + if (process.send) { + process.send({ from: 'child' }); + } +}, 1000) \ No newline at end of file diff --git a/lib/forever/monitor.js b/lib/forever/monitor.js index c6e0208a..5802d141 100644 --- a/lib/forever/monitor.js +++ b/lib/forever/monitor.js @@ -9,6 +9,7 @@ var events = require('events'), fs = require('fs'), path = require('path'), + fork = require('child_process').fork, spawn = require('child_process').spawn, broadway = require('broadway'), psTree = require('ps-tree'), @@ -156,9 +157,17 @@ Monitor.prototype.start = function (restart) { self.emit(restart ? 'restart' : 'start', self, self.data); }); + function reemit() { + self.emit.apply(self, arguments); + } + + // Re-emit messages from the child process + this.child.on('message', reemit); + child.on('exit', function (code) { var spinning = Date.now() - self.ctime < self.minUptime; self.warn('Forever detected script exited with code: ' + code); + child.removeListener('message', reemit); function letChildDie() { self.running = false; @@ -200,6 +209,9 @@ Monitor.prototype.start = function (restart) { // trying to execute a script with an env: e.g. node myfile.js // Monitor.prototype.trySpawn = function () { + var execPath = process.execPath, + forked; + if (this.command === 'node' || (this.checkFile && !this.childExists)) { try { var stats = fs.statSync(this.args[0]); @@ -213,7 +225,14 @@ Monitor.prototype.trySpawn = function () { this.spawnWith.cwd = this.cwd || this.spawnWith.cwd; this.spawnWith.env = this._getEnv(); - return spawn(this.command, this.args, this.spawnWith); + if (this.command === 'node' || this.fork) { + process.execPath = this.command; + forked = fork(this.options[0], this.options.slice(1), this.spawnWith); + process.execPath = execPath; + return forked; + } + + return spawn(this.command, this.options, this.spawnWith); }; // diff --git a/test/fork-test.js b/test/fork-test.js new file mode 100644 index 00000000..5b669e04 --- /dev/null +++ b/test/fork-test.js @@ -0,0 +1,29 @@ +/* + * spin-test.js: Tests for spin restarts in forever. + * + * (C) 2010 Nodejitsu Inc. + * MIT LICENCE + * + */ + +var assert = require('assert'), + path = require('path'), + vows = require('vows'), + forever = require('../lib/forever'); + +vows.describe('forever/spin-restart').addBatch({ + "When using forever": { + "and spawning a script that uses `process.send()`": { + topic: function () { + var script = path.join(__dirname, '..', 'examples', 'process-send.js'), + child = new (forever.Monitor)(script, { silent: true, minUptime: 2000, max: 1 }); + + child.on('message', this.callback.bind(null, null)); + child.start(); + }, + "should reemit the message correctly": function (err, child, spinning) { + console.dir(arguments); + } + } + } +}).export(module);