node.js process.hrtime in asynchronous server? - javascript

I create a http server using http.createServer(onRequest) and want to measure time needed to make a response.
Currently, in my onRequest handler I do:
var start = process.hrtime();
response.on('end', function (){
console.log('time to respond', process.hrtime(start));
});
// call various asynchronous functions and send them 'response' object. One of them eventually does response.end()
I'm worried if this will work fine when a bunch of requests comes instantly, or will asynchronism break it/mix-up times?

You should do somethinng like,
function measureRequestTime (req, res, next) {
var start = process.hrtime();
response.on('end', function () {
// logging the time here..
});
}
// app init
app.use(meastureTime);

The variable will be in the closure scope of your onRequest handler function so it'll work just the way you expect it to (assuming process.hrtime does what you want).

Related

How are callback functions executed in node.js?

I've just started learning node.js and express and there's something that confuses me a bit in the "hello world" example on the express.js website. In the example, they refer to the server variable inside the callback function.
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('App listening at http://%s:%s', host, port);
});
Does app.listen() return a value to server variable before it executes the callback function? How can it do that and how does it work? Is this the same for all callback functions in node (and javascript)?
I would just like a simple explanation of the execution process.
To be clear, I understand that the callback function has access to the server variable. But if the app.listen method executes the callback function before it returns a value to the server variable, wouldn't that mean that the server variable is still underfined when you try to access server.adress()? That is what I don't understand.
Does app.listen() return a value to server variable before it executes the callback function?
Yes, exactly. app.listen() resembles to the plain Node.js server.listen method.
The callback is an shortcut for assigning the server an listener to the listening event.
You could do the same with the following code:
var server = app.listen( 3000 );
server.on( "listening", function () {
console.log( "server is listening in port 3000" );
});
How can it do that and how does it work? Is this the same for all callback functions in node (and javascript)?
This happens because IO events in Node.js are all run asynchronously (with exceptions from the fs module) - this is, they will only take place when other synchronous code have finished to run.
This works the same in browser JS - if you run some JS process synchronously, any events triggered (like click, blur, etc) will only execute after that one finishes.
A function has access to all the variables that existed in the scope where it was created (unless it masks them).
var in_the_global_scope = 1;
function outer() {
function inner() {
alert(in_the_global_scope);
}
inner();
}
inner has access to any variable declared in inner, outer and the global scope.
A function being a callback isn't really relevant.
The listen method itself doesn't have access to server because listen was created in a different scope.
But if it returns a value, how can it then execute the callback function?
Because it doesn't just execute the callback. It waits for an event and the callback gets fired in reaction to that.
var timeOutId = setTimeout(function() {
alert(timeOutId);
}, 1000);
var server is being assigned to the function app.listen()
If you look at the express documentation it states that
The app.listen() method is a convenience method for the following (for HTTP only):
app.listen = function() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
By setting var server = app.listen() and the fact that app.listen() returns something, you're essentially setting var server to whatever app.listen() return.
You can thinking like that, the app.listen() return an object server which include information of how to run the server, example port, address, like a paper of instructions. Then it go to run server.
When server was run, the application also add some remark on that instructions example porcessid
then server is also call callback function app.listen(port[, callback]). Withing that function, we can access server information back from instruction and remarks.

Is there a way to call the each function in synchronous way in node-orm?

I'm having a problem with node-orm2's asynchronous behavior. I have a query like this:
req.models.posts
.find(...)
.order('-whatever')
.each(doMagic) //Problem happens here
.filter(function(post) { ... })
.get(callback);
function doMagic(post, i) {
post.getMagic(function(err, magic) {
...
});
};
My problem is that, since what happens inside post.getMagic() is asynchronous, my callback function gets executed before doMagic finishes. Checking the source code I verified this is the normal behavior, but since this is an express app, my server responds with the wrong information.
I tried using waitfor to make the call to getMagic synchronous, with no success. This is probably something I'm missing. Is there a way to make the each function work like a synchronous map function?
Change your code to get posts and once you have them iterate over them using async.js and once done send response.
Something like:
var async = require('async');
req.models.posts
.find(...)
.order('-whatever')
.each()
.filter(function(post) {...
})
.get(function(posts) {
//iterate over posts here
async.eachSeries(posts, function(file, callback) {
post.getMagic(function(err, magic) {
//here comes the magic
//and then callback to get next magic
callback();
});
}, function(err) {
//respond here
});
});

Calling an exported function from within the same module

If you have a function like this in a module:
dbHandler.js
exports.connectSQL = function(sql, connStr, callback){
////store a connection to MS SQL Server-----------------------------------------------------------------------------------
sql.open(connStr, function(err, sqlconn){
if(err){
console.error("Could not connect to sql: ", err);
callback(false); //sendback connection failure
}
else{
callback(sqlconn); //sendback connection object
}
});
}
Can you call this from inside the same module it's being defined? I want to do something like this:
later on inside dbHandler.js
connectSQL(sql, connStr, callback){
//do stuff
});
Declare the function like a regular old function:
function connectSQL(sql, connStr, callback){
////store a connection to MS SQL Server------------------------------------
sql.open(connStr, function(err, sqlconn){
// ...
and then:
exports.connectSQL = connectSQL;
Then the function will be available by the name "connectSQL".
There are any number of ways to accomplish this, with Pointy's being my preferred method in most circumstances, but several others depending on the situation may be appropriate.
One thing you will see often is something like this:
var connectSQL = exports.connectSQL = function(sql, connStr, callback) { /*...*/ };
Technically, though I've never actually seen someone do this, you could use the exports object inside your module without issue:
// later on inside your module...
exports.connectSQL('sql', 'connStr', function() {});
Beyond that, it comes down to whether it matters whether you have a named function, like in Pointy's example, or if an anonymous function is ok or preferred.

Efficiency with JavaScript Callbacks

I just wanted to confirm a suspicion of mine.
I stumbled across an article which recommended using Socket.io in the following fashion:
var app = require('express').createServer()
var io = require('socket.io').listen(app);
app.listen(8080);
// Some unrelated stuff
io.sockets.on('connection', function (socket) {
socket.on('action1', function (data) {
// logic for action1
});
socket.on('action2', function (data) {
// logic for action2
});
socket.on('disconnect', function(){
// logic for disconnect
});
});
I feel like the following would be a better use of resources:
var app = require('express').createServer()
var io = require('socket.io').listen(app);
app.listen(8080);
// Some unrelated stuff
io.sockets.on('connection', function (socket) {
socket.on('action1', action1);
socket.on('action2', action2);
socket.on('disconnect', disconnect);
});
function action1(data) {
// logic for action1
}
function action2(data) {
// logic for action2
}
function disconnect() {
// logic for disconnect
}
My feeling is that although the anonymous function that handles the connection event is only created in memory once, the anonymous functions that handle action1, action2, and disconnect are created in memory for every socket connection. The issue with the second approach is that socket is no longer in scope.
So firstly, is my suspicion about the creation of functions true? And secondly, if so is there a way to get socket in scope for the named functions?
Using a closure helps to keep the scope clean:
io.sockets.on('connection', function () {
function action1(data) {
// logic for action1
}
function action2(data) {
// logic for action2
}
function disconnect() {
// logic for disconnect
}
return function (socket) {
socket.on('action1', action1);
socket.on('action2', action2);
socket.on('disconnect', disconnect);
}
}()); // <- note the immediate function call
To your questions:
So firstly, is my suspicion about the creation of functions true?
Yes. The closure approach above prevents this, the callback functions are created only once. Plus: all see the correct parent scopes.
And secondly, if so is there a way to get socket in scope for the named functions?
The socket will be available as this in the callbacks.
You're correct, that the anonymous methods are created for each connection - and if you don't need scope, then the second method does avoid that. If you need the socket scope there's no real way to avoid it. If you want to keep the methods external (for some other reason) and still keep scope, you could always:
//...
socket.on('action1', function(){
action1.apply( socket, arguments );
} );
//... and so forth.
But that has you back to creating a method signature for each connection, so I'm not sure what you'd be gaining.

Using factory methods as alternative to passing anonymous functions

I was watching a video on node.js and I saw the speaker say, he prefers to do this instead of using anonymous call backs:
var server = Server.createServer(server.createReq(req,res));
I think its nice too that a named function with parameters can be passed instead of an anonymous function with closure.
Question 1: However the implementation of the createReq probably returns an anonymous function, wouldn't it?
How is this better? I can see it being better because unlike the closure at the createServer level, a closure at the createReq level is more contained - it would not store reference to other unnecessary variables (non req,res).
And as the speaker said, I guess this would help visualize realtionships better between the different parts of the code.
Question 2: Are there any other benefits?
A reason why you might want to call a function that returns a function may be that you are starting multiple servers within the same process, and you want them to share the same request handler.
Another thing to keep in mind is that each anonymous function must be allocated on the heap, and thus incurs some garbage collection overhead. By using a named function instead of an anonymous function, you can sometimes reduce this cost.
For example, maybe something like this untested and incomplete example:
var server = Server.createServer(handleRequest);
function handleRequest(req, res) {
new Client(req, res);
}
function Client(req, res) {
this.req = req;
this.res = res;
this.body = "";
req.on("data", function (chunk) {
self.onData(chunk);
});
}
Client.prototype.onData = function (chunk) {
this.body += chunk.toString();
};
This example uses a small anonymous function to bind the data event callbacks back to the specific instance of Client, but all other functions are named.

Categories