Angel \”Java\” Lopez on Blog

September 9, 2011

AjFabriq on NodeJs (Part 3) A Distributed Simple Application

Filed under: AjFabriq, Distributed Computing, JavaScript, NodeJs, Open Source Projects — ajlopez @ 11:22 am

Previous Post

Lets run our “killer” application (a simple counter) in two node. At the repo, under examples\numbers, I have an appserver.js program:

It’s similar to my local example. The difference is that the top message processor is listening using a port:

/**
 * Host.
 */
var host = ajfabriq.createLocalHost();
/**
 * Application configuration.
 */
 
var app = host.createProcessor('numbers', 'application');
var node = app.createProcessor('processor', 'node');
node.on('decrement', function (message) {
	console.log("Processing number " + message.number);
	
	if (message.number <= 1) {
		console.log("End Processing");
		return;
		}
		
	var number = message.number-1;
	
	this.post({ action: 'decrement', number: number });
});
host.listen(3000);
host.process({ application: 'numbers', node: 'processor', action: 'decrement', number: 10 });

In this code, I’m using ajfabriq.createLocalHost() instead .createProcessor(). And host.listen(3000) to accept messages from other nodes.

I run another program: appclient.js. It has the same local processors:

/**
 * Application configuration.
 */
 
var app = host.createProcessor('numbers', 'application');
var node = app.createProcessor('processor', 'node');
node.on('decrement', function (message) {
	console.log("Processing number " + message.number);
	if (message.number <= 1)
		return;
		
	var number = message.number-1;
	
	this.post({ action: 'decrement', number: number });
});

But it connects to the first server, and post a new message:

var socket = new net.Socket();
socket.connect(3000, 'localhost',
	function() {
		host.connect(new ajfabriq.Channel(socket), true);
		socket.write(JSON.stringify({name : 'ajfmessage', message: { application: 'numbers', node: 'processor', action: 'decrement', number: 10 }}));
	}
);
	

ajfabriq.Channel is the bidirectional channel between two ajfabriq servers.

This server output:

Note the interchange of message between the two servers, at the beginning. They are informing their local processors, so each server knows if a message could be processed by another server.

The first server reaction:

Some of the numbers are processed by the second server, and the others are routed to the first server. The routing is a simple random choice in this demo. LocalHost objects have a new .post message:

LocalHost.prototype.post = function (message) {
	var hosts = [ this ];
	
	for (var remote in this.remotes) {
		if (this.remotes[remote].accepts(message)) {
			hosts.push(this.remotes[remote]);
		}
	}
	var n = Math.floor(Math.random() * hosts.length);
	
	hosts[n].process(message);
};

Next steps: better routing, improve socket communication (large JSON messages detection and split), logging, more sample apps.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

September 8, 2011

AjFabriq on NodeJs (Part 2) A local Simple Application

Filed under: AjFabriq, Distributed Computing, JavaScript, NodeJs, Open Source Projects — ajlopez @ 11:40 am

Previous Post
Next Post

Lets explore how to use AjFabriq on NodeJs. Here is a simple application:

https://github.com/ajlopez/AjFabriqJs/tree/master/examples/numbers

It implements the ultimate killer application: it receives a message with a number, and post a message with the number less one ;-). Let’s see how the application is defined:

/**
 * Module dependencies.
 */
 
var ajf = require('ajfabriq');

I included c:\Git in my NODE_PATH environment variable, and there is a c:\Git\ajfabriq containing my git local repo under development. You can clone the repo in your node_modules folder if you are using NodeJs 5.x (see Playing With NodeJs (1) Running on Windows (and Azure)) .

AjFabriq defines an object that exposes some methods. This is the way to create a message processor that is local, and it is not exposed to other servers (a distributed example in the repo, to review in an upcoming post):

/**
 * Host.
 */
var host = ajf.createProcessor();

Now, a message processor (see previous post) can be a composite. The aprocessor.createProcessor creates a new processor and adds it to the parent processor:

/**
 * Application configuration.
 */
 
var app = host.createProcessor('numbers', 'application');
var node = app.createProcessor('processor', 'node');

The first processor, app, will accept and process messages with property “application” having "numbers” as value. Its child processor node will process message with additional property “node” with value “processor”. In this way, we can define a tree of message processors. The message properties and their values are the routing information, so each message will be send to the appropriate message processor.

But, how to define the leaf processor behavior? To be aligned to NodeJs async processing, each processor inherits from an EventEmitter. Since the previous post, I defined the Processor as a “subclass” of process.EventEmitter in AjFabriq code:

var EventEmitter = process.EventEmitter;
// ...
function Processor(name, kind)
{
	this.name = name;
	this.kind = kind;
	this.processors = [];
}
Processor.prototype.__proto__ = EventEmitter.prototype;

Now, we can define the leaf processor behavior:

node.on('decrement', function (message) {
	console.log("Processing number " + message.number);
	
	if (message.number <= 1) {
		console.log("End Processing");
		return;
		}
		
	var number = message.number-1;
	
	this.post({ action: 'decrement', number: number });
});

The message processing detects an action property, and raise the corresponding event. Note the emit method invocation in AjFabriq code:

Processor.prototype.process = function (message)
{
	if (this.processors == null || this.processors.length == 0) {
		this.emit(message.action, message);
		return;
	}
	
	for (var processor in this.processors)
		if (this.processors[processor].accepts(message)) 
		{
			this.processors[processor].process(message);
		}
}

 

At the end of my “killer” app sample, a message is sent to the top processor:

host.process({ application: 'numbers', node: 'processor', action: 'decrement', number: 10 });

The output:

But wait! Do you check the ‘decrement’ code I commented above? There is a:

this.post({ action: 'decrement', number: number });

No application, node properties!! Yes, it's right. If you post a message from a processor (node in this case), the parent processors fill the missing properties. That is, application property is set to “numbers”, and node property is set to “processor”. If you want to sent a message to other application, you can explicitly set the corresponding property in your new message. Note that the recommended practice is: don't change the original message. Maybe it could be processed by other processors.

For upcoming posts: new apps, a distributed example, more fun! ;-)

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

August 25, 2011

AjFabriq on NodeJs (Part 1) Introduction

Filed under: AjFabriq, Distributed Computing, JavaScript, NodeJs, Open Source Projects — ajlopez @ 10:28 am

Next Post

Some years ago I discovered Fabriq project (thanks @asehmi!):

Remember Fabriq
FABRIQ has gone public!
Arvindra Shemi Fabriq Articles
Clemens Vasters Fabriq Articles

Key points:

FABRIQ is an infrastructure for constructing networks of nodes processing and relaying messages. These nodes are hosted in machines running into a serviced application.

You can have multiple machines running the same or different applications. The “network” is the application, “node” is a collection of “actions”, and each action process a message. More doc:

These nodes can be hosted in any distribution on several machines according to a defined configuration, so there may be machines running a single node or several nodes, this association are made by specifying the host-name or machine identification associated with each node in the network.

Each of these machines is running a serviced application responsible for starting and stopping its Host and Nodes which are the application main components. The host is responsible for handling the configuration, loading and unloading nodes and receives the messages and delivers them to the appropriate Node.

Past weekend, I started a Javascript project to run on NodeJs, based on Fabriq ideas:

A Distributed Application Framework for NodeJs https://github.com/ajlopez/AjFabriqJs

Simple one file implementation. Four Javascript “Classes”.

I want to run many NodeJs servers that hosts AjFabriq applications, sending messages across their network:

Original Fabriq had application, nodes, configuration. I simplified it and now I have a simple Processor that accepts messages. It can produce 0, 1 or more messages:

Messages are schema-less JSON objects that contains its own routing information:

A Processor could handle all the messages containing the key/value application: “webcrawler”. Some processors are composites: they have another processors. Then, the webcrawler processor could have a child processor specialized in handle message with key/value node:”downloader”. See the picture? But the key/values and the deep of processor trees ARE DECIDED by the developer. You decide to have “applications”, “actions”, “nodes”, or whatever you want.

A host can have many processor defined. When message is posted, a simple local method decides where to send it. It could be locally processed or it could be send to a remote host. The host network is dynamic: a new host can be added at any time, then it can collaborate with the current messages processing.

Pending topics for upcoming blog posts: implementation details, the simplest application, using net (plain) sockets, my failure with Socket.IO. Work in progress: make AjFabriq more NodeJs friendly using EventEmitter in key points, host info (hosted application) better dissemination, more robust implementation; rename Socket to Channel, a better description word.

My previous work on distributed application samples:

AjMessages
AjAgents

Keep tuned!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Theme: Shocking Blue Green. Get a free blog at WordPress.com

Follow

Get every new post delivered to your Inbox.

Join 67 other followers