Prash's Blog

Split nodejs blocking operation using process.nextTick May 2, 2012

Filed under: Nodejs — prazjain @ 9:16 am
Tags:

This is part of a multipart nodejs series.
In the previous post for basic nodejs application, you have seen a blocking / long running user operation hogging cpu in node. Single node is single threaded and runs only on a single core, a single blocking request and bring your web app to a halt. To get away with this, you can use process.nextTick to execute a particular function through the event loop.
Here we will refine on the fibonacci function defined earlier, and add a new function in math.js :

var fibonacciAsync = exports.fibonacciAsync = function(n, done)
{
	if (n==1 || n ==2)
	{
		done(1);
	}
	else
	{
		process.nextTick(function() 
		{
			fibonacciAsync( n -1 , function(val1)
			{
				process.nextTick(function() 
				{
					fibonacciAsync( n -2, function(val2)
					{
						done(val1 + val2);
					});
				});
			});
		});
	}
}

Create another module fibo2-node.js :

var htutil = require('./htutil');
var math = require('./math');
function sendResult(req, res, a, fiboval)
{
	res.writeHead(200, { 'Content-Type': 'text/html' } );
	res.end(htutil.page("Fibonacci", htutil.navbar(), 
				[
				(!isNaN(fiboval) ? ("<p class='result'>fibonacci {a} = {fibo}</p>"
				.replace("{a}",a)
				.replace("{fibo}",fiboval))
				: "" ),
				"<p>Enter a number to see its fibonacci</p>",
				"<form name='fibonacci' action='/fibonacci' method='get'>",
				"A: <input type='text' name='a' />",
				"<input type='submit' value='Submit' />",
				"</form>"
				].join('\n')
				)
			);				
}

exports.get = function(req, res)
{
	if(!isNaN(req.a))
	{
		math.fibonacciAsync(Math.floor(req.a), function(val)
		{
			sendResult(req,res, Math.floor(req.a), val);
		});
	}
	else
	{
		sendResult(req,res,NaN,NaN);
	}
}

Change app-node.js to call fibo2-node module when it get /fibonacci requests like this :

                                        .....
					else if (req.params.pathname === "/fibonacci")
					{
						require("./fibo2-node").get(req,res);
					}
                                        .....

Now if you run the app :

node app-node.js

Hit the url : http://localhost:8124, for fibonacci enter the value like 50, while it is processing this request, in another window open the same url and you can see that the server can handle the new request. This is because the earlier fibonacci implementation would hog all the cpu for itself until it finished the computation and no other request will be processed. But now the cpu is responsive to other requests as well.

An interesting observation here is that if you try fibonacci for 40 in previous implementation it will probably return in few seconds, but with new implementation my request timed-out, which is probably a side-effect of spilt a small task into a large number of very small task to keep the cpu responsive to other requests.
Go back to the main nodejs tutorial.

Advertisements
 

4 Responses to “Split nodejs blocking operation using process.nextTick”

  1. […] Execute tasks asynchronously in Nodejs event loop. […]

  2. […] but not least our friend Prash has refactored the original fibonacci function to be handled in slices which allows it to bind against the event loop ticks. That way it can […]

  3. This is not a legitimate way of working with node.js. I agree you can use time slicing and give an illusion of responses being served parallely, but unfortunately it takes a big hit on the response times. The optimal way of solving this problem is via the cluster module.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s