Permalink
Browse files

cleanup of the example and now only sending 'idle' when there are rea…

…lly no pending messages.
  • Loading branch information...
1 parent 77f52a4 commit 6a2565cf6126f98b20324d5d45b1617619a35697 Joachim Kainz committed Sep 26, 2011
Showing with 109 additions and 44 deletions.
  1. +49 −19 README.md
  2. +4 −5 examples/master.js
  3. +16 −9 examples/worker.js
  4. +33 −7 lib/backgrounder-launcher.js
  5. +7 −4 lib/backgrounder.js
View
@@ -9,35 +9,65 @@ There are a lot of other, similar libraries for Node.js out there, that do simil
* Allows users to implement code that is compatible with the [``child_process.fork``](http://nodejs.org/docs/v0.5.6/api/all.html#child_process.fork) call available with v0.5.*.
* Child processes can use ``console.log`` and other console function; the logs are printed by the main process.
-Here is exampe for a master:
+Here is example for a master:
```
-var util = require("util");
var backgrounder = require("backgrounder");
-var worker = backgrounder.spawn("./worker");
-
+var worker = backgrounder.spawn(__dirname + "/worker.js");
worker.on("message", function(message) {
- console.log(util.inspect(message, false, 100));
+ console.log("Master: received message ", message);
});
-
-worker.send({
- "title": "hello world!",
- "flag": true
+var counter = 0;
+worker.on("idle", function(message) {
+ switch (counter ++) {
+ case 0:
+ console.log("Master: worker idle after configuration");
+ worker.send({
+ "title": "hello world!",
+ "flag": true
+ });
+ return;
+ case 1:
+ console.log("Master: worker idle after messge, calling terminte...");
+ worker.terminate();
+ return;
+ default:
+ console.error("Master: unexpected idle message ", counter, message);
+ }
+});
+worker.config({
+ "primaryDirective": "don't interfere",
+ "overdrive": true
});
```
-This could be the code of the client:
-
-```
-var util = require("util");
-
-console.log('Started the worker');
+Here is a sample for a worker that shows how to process messages from there master:
+process.on('config', function(config) {
+ console.log('Worker: received configuration ', config);
+});
process.on('message', function(message) {
- console.log('Worker received: %s', util.inspect(message, false, 100));
-
+ console.log('Worker: echoing ', message);
process.send({
- "received": message
+ "Worker received": message
});
});
-```
+process.on('terminate', function() {
+ console.log('Worker: asked to terminate');
+});
+console.log('Worker: Started!');
+```
+
+The output when running the master looks like this:
+
+```
+jfk@graz:~/workspace/1/backgrounder$ node examples/master.js
+Worker: Started!
+Worker: received configuration { primaryDirective: 'don\'t interfere',
+ overdrive: true }
+Master: worker idle after configuration
+Worker: echoing { title: 'hello world!', flag: true }
+Master: received message { 'Worker received': { title: 'hello world!', flag: true } }
+Master: worker idle after messge, calling terminte...
+Worker: asked to terminate
+```
View
@@ -1,4 +1,3 @@
-var util = require("util");
var backgrounder = require("../lib/backgrounder");
//
// Spawn the worker in a backround proccess
@@ -8,7 +7,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("master received the following messge from the worker: ", message);
+ console.log("Master: received message ", message);
});
//
// Process messages that indicate that the workder has become idle. Both worker.config as well as
@@ -19,7 +18,7 @@ var counter = 0;
worker.on("idle", function(message) {
switch (counter ++) {
case 0:
- console.log("worker notified master that the configuration completed");
+ console.log("Master: worker idle after configuration");
//
// Send a message to the
//
@@ -29,11 +28,11 @@ worker.on("idle", function(message) {
});
return;
case 1:
- console.log("worker notified master that the message it had sent was process, terminating...");
+ console.log("Master: worker idle after messge, calling terminte...");
worker.terminate();
return;
default:
- console.error("unexpected idle message ", counter, message);
+ console.error("Master: unexpected idle message ", counter, message);
}
});
//
View
@@ -1,18 +1,25 @@
-var util = require("util");
-
+//
+// Deal with configuration messages sent from the master
+//
+process.on('config', function(config) {
+ console.log('Worker: received configuration ', config);
+});
+//
+// Set up a message handler from messages sent from the master
+//
process.on('message', function(message) {
- console.log('Worker received a message from the master and is sending it back: ', message);
+ console.log('Worker: echoing ', message);
process.send({
- "client received": message
+ "Worker received": message
});
});
-process.on('config', function(config) {
- console.log('Worker received the following configuration from the master: ', config);
-});
+//
+// Set up a handler that lets the user know that we have been asked to terminate
+//
process.on('terminate', function() {
- console.log('Worker received a request to termine from the master');
+ console.log('Worker: asked to terminate');
});
//
// Let the users know that we are started. Logs are forwarded to the parent process and printed there.
//
-console.log('Started the worker');
+console.log('Worker: Started!');
@@ -72,6 +72,9 @@ console.dir = function(object) {
var message = util.inspect(object);
log(message);
};
+//
+// Reimplement timer functionality
+//
var times = {};
console.time = function(label) {
times[label] = Date.now();
@@ -80,9 +83,18 @@ console.timeEnd = function(label) {
var duration = Date.now() - times[label];
console.log('%s: %dms', label, duration);
};
+//
+// Buffer for processing messages
+//
var buffer = "";
+//
+// Our private event emitter
+//
var emitter = new events.EventEmitter();
-
+//
+// Process a message by sending it to all the listeners. If the message is a terminate message, we want
+// to exit the process.
+//
function processMessage(message) {
var parsed = JSON.parse(message);
@@ -92,7 +104,9 @@ function processMessage(message) {
process.exit(0);
}
}
-
+//
+// Process an array of messages
+//
function processMessages(messages) {
_.each(messages, function(message){
if (message.length > 0) {
@@ -101,21 +115,25 @@ function processMessages(messages) {
}
finally {
var json = JSON.stringify({
- "type": "idle",
- "content" : message
+ "type": "completed"
});
process.stdout.write(json + '\n');
}
}
});
}
-
+//
+// Find the message in a buffer and process them
+//
function processBuffer() {
var messages = buffer.split('\n');
buffer = "";
processMessages(messages);
}
+//
+// Set up the input channel
+//
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(data) {
@@ -124,6 +142,9 @@ process.stdin.on('data', function(data) {
processBuffer();
}
});
+//
+// Allow users to register for our events using v0.5 facilities
+//
var process_on = process.on;
process.on = function(message, listener) {
if ("message" === message || "terminate" === message || "config" === message) {
@@ -133,6 +154,9 @@ process.on = function(message, listener) {
process_on.call(console, message, listener);
};
+//
+// Send a message to the parent using v0.5 facilities
+//
process.send = function(message) {
var json = JSON.stringify({
"type": "message",
@@ -141,5 +165,7 @@ process.send = function(message) {
process.stdout.write(json + '\n');
};
console.info = console.log;
-var module = process.argv[2];
-require(module);
+//
+// Load the module the users wanted to load
+//
+require(process.argv[2]);
View
@@ -11,11 +11,13 @@ function processMessage(child, message) {
console.log(message.content);
}
else if (message.type === 'message') {
- child.emitter.emit('message', message.content);
+ child.emitter.emit(message.type, message.content);
}
- else if (message.type === 'idle') {
- child.emitter.emit('idle', message.content);
- child.pending --;
+ else if (message.type === 'completed') {
+ child.emitter.emit(message.type, message.content);
+ if (0 === --child.pending) {
+ child.emitter.emit('idle', message.content);
+ }
}
else {
console.error("unexpected message %s", util.inspect(message));
@@ -41,6 +43,7 @@ function Child(module) {
var self = this;
this.busy = false;
this.buffer = "";
+ this.pending = 0;
var path = __dirname + '/backgrounder-launcher.js';
this.emitter = new events.EventEmitter();
this.process = cp.spawn('node', [path, module]);

0 comments on commit 6a2565c

Please sign in to comment.