Navigation Menu

Skip to content

Commit

Permalink
added documentation and fixed small issues.
Browse files Browse the repository at this point in the history
  • Loading branch information
Joachim Kainz committed Sep 26, 2011
1 parent d519882 commit 77f52a4
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 52 deletions.
29 changes: 17 additions & 12 deletions examples/master.js
Expand Up @@ -8,7 +8,7 @@ var worker = backgrounder.spawn(__dirname + "/worker.js");
// For this demo, let's just print any message we are receiving from the worker
//
worker.on("message", function(message) {
console.log(util.inspect(message, false, 100));
console.log("master received the following messge from the worker: ", message);
});
//
// Process messages that indicate that the workder has become idle. Both worker.config as well as
Expand All @@ -17,12 +17,24 @@ worker.on("message", function(message) {
//
var counter = 0;
worker.on("idle", function(message) {
if (0 === counter ++) {
console.log("configuration completed");
switch (counter ++) {
case 0:
console.log("worker notified master that the configuration completed");
//
// Send a message to the
//
worker.send({
"title": "hello world!",
"flag": true
});
return;
case 1:
console.log("worker notified master that the message it had sent was process, terminating...");
worker.terminate();
return;
default:
console.error("unexpected idle message ", counter, message);
}

worker.terminate();
});
//
// This is optional, but some workers need to be configured. This call sends a message, which triggers
Expand All @@ -32,10 +44,3 @@ worker.config({
"primaryDirective": "don't interfere",
"overdrive": true
});
//
// Send a message to the
//
worker.send({
"title": "hello world!",
"flag": true
});
18 changes: 14 additions & 4 deletions examples/worker.js
@@ -1,8 +1,18 @@
var util = require("util");
console.log('Started the worker');

process.on('message', function(message) {
console.log('Worker received: %s', util.inspect(message, false, 100));
console.log('Worker received a message from the master and is sending it back: ', message);
process.send({
"received": message
"client received": message
});
});
});
process.on('config', function(config) {
console.log('Worker received the following configuration from the master: ', config);
});
process.on('terminate', function() {
console.log('Worker received a request to termine from the master');
});
//
// Let the users know that we are started. Logs are forwarded to the parent process and printed there.
//
console.log('Started the worker');
50 changes: 32 additions & 18 deletions lib/backgrounder-launcher.js
@@ -1,7 +1,9 @@
var util = require('util');
var events = require("events");
var _ = require("underscore");

//
// Format a log message; this code is adopted from node.js code.
//
function format(f) {
var i;
if (typeof f !== 'string') {
Expand Down Expand Up @@ -36,23 +38,36 @@ function format(f) {

return str;
}

//
// Deal with uncaught exceptions by just printing it to stderr. This error will be forwarded to the parent
// process and printed there.
//
process.on('uncaughtException', function(err) {
console.log(err.stack);
});

//
// Send a log message to the parent process by wrapping it into a JSON message of type "console".
// This type of message is unwrapped on the server and printed to stdout.
//
function log(message) {
var _message = {
var json = JSON.stringify({
"type": "console",
"content": message
};
var json = JSON.stringify(_message);
});
process.stdout.write(json + '\n');
}
//
// Change the console.log to a message to that calls the local log message, which wraps the message in JSON and
// sends them to the server to be written to stdout there.
//
console.log = function() {
var message = format.apply(this, arguments);
log(message);
};
//
// Change the console.dir to a message to that calls the local log message, which wraps the message in JSON and
// sends them to the server to be written to stdout there.
//
console.dir = function(object) {
var message = util.inspect(object);
log(message);
Expand All @@ -69,10 +84,6 @@ var buffer = "";
var emitter = new events.EventEmitter();

function processMessage(message) {
if (message.length <= 0) {
return;
}

var parsed = JSON.parse(message);

emitter.emit(parsed.type, parsed.content);
Expand All @@ -84,14 +95,17 @@ function processMessage(message) {

function processMessages(messages) {
_.each(messages, function(message){
try {
processMessage(message);
}
finally {
var json = JSON.stringify({
"type": "idle"
});
process.stdout.write(json + '\n');
if (message.length > 0) {
try {
processMessage(message);
}
finally {
var json = JSON.stringify({
"type": "idle",
"content" : message
});
process.stdout.write(json + '\n');
}
}
});
}
Expand Down
59 changes: 41 additions & 18 deletions lib/backgrounder.js
Expand Up @@ -2,7 +2,10 @@ var _ = require("underscore");
var cp = require("child_process");
var events = require("events");
var util = require("util");

//
// Process a message from the child. Message supported are of type 'console', 'message', and 'idle'.
// 'idlle' messages decrement the message pending count of the child.
//
function processMessage(child, message) {
if (message.type === 'console') {
console.log(message.content);
Expand All @@ -11,14 +14,16 @@ function processMessage(child, message) {
child.emitter.emit('message', message.content);
}
else if (message.type === 'idle') {
child.emitter.emit('idle');
child.busy = true;
child.emitter.emit('idle', message.content);
child.pending --;
}
else {
console.error("unexpected message %s", util.inspect(message));
}
}

//
// Process the content of self.buffer. Find all message in the buffer and process the messages.
//
function processBuffer(self) {
var messages = self.buffer.split('\n');
self.buffer = "";
Expand All @@ -29,13 +34,16 @@ function processBuffer(self) {
}
});
}

function Child(mdl, module) {
//
// Create a new child process passing the file to be executed by the launched process.
//
function Child(module) {
var self = this;
this.busy = false;
this.buffer = "";
var path = __dirname + '/backgrounder-launcher.js';
this.emitter = new events.EventEmitter();
this.process = cp.spawn('node', [mdl, module]);
this.process = cp.spawn('node', [path, module]);
this.process.stdout.on('data', function(data) {
self.buffer += data.toString();
if (self.buffer.substr(-1) === '\n') {
Expand All @@ -50,33 +58,48 @@ function Child(mdl, module) {
console.error(_data);
});
}
//
// Allow users to register from messages from the client
//
Child.prototype.on = function(event, listener) {
this.emitter.on(event, listener);
};
//
// Send a message to the client (do the actual work: stringify, write to stdin, increment the pending counter)
//
function sendMessage(child, message) {
var json = JSON.stringify(message);

child.pending ++;
child.process.stdin.write(json + '\n');
};
//
// Send a user-defined message to the client
//
Child.prototype.send = function(message) {
var json = JSON.stringify({
sendMessage(this, {
"type": "message",
"content": message
});
this.busy = true;
this.process.stdin.write(json + '\n');
};
//
// Tell the client to (re-)configure itself
//
Child.prototype.config = function(config) {
var json = JSON.stringify({
sendMessage(this, {
"type": "config",
"content": config
});
this.busy = true;
this.process.stdin.write(json + '\n');
};
//
// Tell the client to shut down
//
Child.prototype.terminate = function() {
var json = JSON.stringify({
sendMessage(this, {
"type": "terminate"
});
this.busy = true;
this.process.stdin.write(json + '\n');
};
// export the spwan method, which creates the client object.
module.exports.spawn = function(module) {
var mdl = __dirname + '/backgrounder-launcher.js';
return new Child(mdl, module);
return new Child(module);
};

0 comments on commit 77f52a4

Please sign in to comment.