Node.JS for startups or problems on production
Good day. I would like to share with the habro-community about my experience in using Node.JS on a live project. Five months ago, I began to implement one of my old ideas - the service of achievements.
When developing projects, I prefer to adhere to the point of view that the choice of technology should be justified by the low cost of its use. Therefore, for my project, I chose the stack - Node.JS + mongoDB, as these are the technologies that I know best.
I want to note that here I will describe only those problems that I myself encountered.
Node.JS is known for its ideology in that all I / O calls must occur asynchronously. This approach provides very broad opportunities, although sometimes it leads to certain problems. For example, a banal situation - it is necessary to make a query to the database and based on the result make another query, for example, to another table. For religious reasons, I did not use mongoose (ORM for mongodb). In this regard, used node-mongodb-native . The problem is that when using this module you have to work with the database cursor, which leads to the appearance of an extra callback:
Thus, the task described above is reduced to a banal call call:
It is customary to solve such problems by using Coffescript or the async module, both of which make the code more readable and adequate. As an intermediate solution, I divided the calls into functions - this option brings the code into a more or less vertical form, but also, with a fairly long chain of calls, it creates the problem of tracking errors in this very chain.
Crashlog in Node.JS in general tasks does not cause any complaints, but sometimes there are executions on which, it is not clear what the error is, only what it is is clear.
By this log it is clear that the error in calling the http module. And if the application has more than one http call? Which one caused the error is not clear. You have to look at the logs on the other side.
Developers using Node.JS are probably familiar with the forever module. This module allows you to run node processes and track its crashes. But the problem is that forever forks itself to track every application you run. As a result, in the top we see N the number of node processes, and it is not clear which of the processes how many resources it consumes. Pid can of course be obtained from the forever list, but this is inconvenient.
Node.JS itself and many modules adhere to CommonJS concepts, in particular, the fact that function execution errors should be returned in the callback as the first argument. In this regard, an error is possible after each I / O call, which can lead to execution. So it is necessary to handle each exception (for this, by the way, Node.JS = is constantly "kicked"). Since my project is at the stage of “deep” beta, I solve such problems “live” ie error handling is only implemented when it begins to occur. Since the application has a modular structure, this is permissible - the user does not see any errors.
That's probably all. It is worth noting that although I described only the negative aspects of Node.JS that I encountered, but for me there are much more positive aspects) Thank you all for your attention)
PS If anyone is interested in a link to the project is in the profile.
When developing projects, I prefer to adhere to the point of view that the choice of technology should be justified by the low cost of its use. Therefore, for my project, I chose the stack - Node.JS + mongoDB, as these are the technologies that I know best.
I want to note that here I will describe only those problems that I myself encountered.
Forced Asynchrony
Node.JS is known for its ideology in that all I / O calls must occur asynchronously. This approach provides very broad opportunities, although sometimes it leads to certain problems. For example, a banal situation - it is necessary to make a query to the database and based on the result make another query, for example, to another table. For religious reasons, I did not use mongoose (ORM for mongodb). In this regard, used node-mongodb-native . The problem is that when using this module you have to work with the database cursor, which leads to the appearance of an extra callback:
db.collection('table', function(err, collection) {
collection.findOne({uid:uid}, function(err, doc) {
cb(doc);
});
});
Thus, the task described above is reduced to a banal call call:
db.collection('table', function(err, collection) {
collection.findOne({uid:uid}, function(err, doc) {
db.collection('table2', function(err, collection) {
collection.findOne({size:doc.size}, function(err, doc) {
cb(doc);
});
});
});
});
It is customary to solve such problems by using Coffescript or the async module, both of which make the code more readable and adequate. As an intermediate solution, I divided the calls into functions - this option brings the code into a more or less vertical form, but also, with a fairly long chain of calls, it creates the problem of tracking errors in this very chain.
Debugging
Crashlog in Node.JS in general tasks does not cause any complaints, but sometimes there are executions on which, it is not clear what the error is, only what it is is clear.
events.js:71
throw arguments[1]; // Unhandled 'error' event
^
Error: socket hang up
at createHangUpError (http.js:1264:15)
at Socket.socketOnEnd [as onend] (http.js:1352:23)
at TCP.onread (net.js:419:26)
By this log it is clear that the error in calling the http module. And if the application has more than one http call? Which one caused the error is not clear. You have to look at the logs on the other side.
Forever
Developers using Node.JS are probably familiar with the forever module. This module allows you to run node processes and track its crashes. But the problem is that forever forks itself to track every application you run. As a result, in the top we see N the number of node processes, and it is not clear which of the processes how many resources it consumes. Pid can of course be obtained from the forever list, but this is inconvenient.
Catching errors
Node.JS itself and many modules adhere to CommonJS concepts, in particular, the fact that function execution errors should be returned in the callback as the first argument. In this regard, an error is possible after each I / O call, which can lead to execution. So it is necessary to handle each exception (for this, by the way, Node.JS = is constantly "kicked"). Since my project is at the stage of “deep” beta, I solve such problems “live” ie error handling is only implemented when it begins to occur. Since the application has a modular structure, this is permissible - the user does not see any errors.
That's probably all. It is worth noting that although I described only the negative aspects of Node.JS that I encountered, but for me there are much more positive aspects) Thank you all for your attention)
PS If anyone is interested in a link to the project is in the profile.