NodeJs request handling on server side - node.js

Hi all Currently My System take multiple request as in queue but when first request take too much time than another requested person have to wait until it's not closed Like FCFS (First come First Serve) algorithm.
Now I want something Like that If 5 Request in queue than Next request has give an error server is too much busy right now Please try after some time.
Please let me know any other Technic that can handle request better than these or any other IDEA please share your thoughts May it's Helpful.
Thanks

I don't think its a good idea to serve only one request at a time. Servers are for handling multiple requests. But if you want to limit requests to 5 you can use use closure variable to achieve the same. e.g. this express router:
var noOfActiveReq = 0;
router.get('/handle', function (req, res) {
if(noOfActiveReq > 5) {
return next(new Error("server is too much busy right now Please try after some time"));
}
noOfActiveReq++;
db.get(req.query.id, function(err, result){
noOfActiveReq--;
if(err) return next(err);
res.json(result);
});
});

Related

Basic GET Request using Express.js & Mongoose

I'm working on an assignment to list all of the data in a mongoDB database, and am having trouble finding where I'm going wrong. It seems like a fairly simple problem, but whenever I run the provided mocha test, it keeps throwing 404 errors. Here is the relevant portion of the test:
it('should it able to retrieve all listings', function(done) {
agent.get('/api/listings')
.expect(200)
.end(function(err, res) {
should.not.exist(err);
should.exist(res);
res.body.should.have.length(147);
done();
});
});
And here is my code for the GET request. I've tried a few different ways of coding it, but this is seems like the simplest/most direct way to return the desired data as JSON.
exports.list = function(req, res) {
Listing.find(function(err, listing){
if(err){
res.status(404).send(err);
} else {
res.json(listing);
}})
};
Is there anything else I should be doing? I've been looking at tutorials and basic examples of requests and it seems like it should work, but it doesn't. Any help would be greatly appreciated.
Make sure that the middleware function (the code for GET request) is mapped to /api/listings
I'm not sure about exports.list. It should probably be module.exports
I'm assuming, based on ur code, that ur using the mongoose ODM. In which case, I think you need to pass a query to the find method check this out
You might wanna make sure that you're connected to the database at the time of test initialization and that that completes before the test starts
It always helps to log errors
Checkout express-generator to scaffold a boilerplate express app. Might help to compare it with your app, to check if it's wired correctly
Seems like you are not passing the first parameter to the find method. Only the callback ... try this:
Listing.find({}, function(err, listing) {
if (err) {
res.status(404).send(err);
} else {
res.json(listing);
}
})
I am assuming you want all records which is why we pass an empty object {}.

NodeJS batching async.parallel

I have
async.parallel(tasksGetContentFromGitHub, function(err, res) {
// all request over, do something
}
the problem is that I might have a large number of tasks, and each of them is sending a request to GitHub.
Since I am a nice citizen, I don't want to send 1000+ queries at once at GitHub, therefore I would like to batch those requests 10 at the time, and then execute my inner code.
Is there an easy way to do that?
You can try async.parallelLimit:
async.parallelLimit(tasksGetContentFromGitHub, 10, function(err, res) {
// all request over, do something
}
Hope that it can help!

node async call return data in response

I am new to nodejs so I have a basic question and this is my scanrio
I have a javascript client which is making a http request to a node server to read a value from the database.
Once the node server receives the request it makes a simple db call and returns the data to the client in the response, and this is where the problem is.
router.get('/state', function(req, res){
var result = dbServer.makeDBCall();//Before this line executes and returns the result the next line executes
res.send(result);
}
The database call from the node server is asynchronous, therefore before the result is returned the node server has already sent a blank response to the client. What is the standard/acceptable way of getting this achieved, I know I can block the node thread using async, but then the whole purpose of node is gone right?
It depends on what kind of database node module you are using.
Other than the standard callback approach, there are also the promise way. The pg-promise library is 1 of those kind.
See sample code:
this.databaseConnection.makeDBCall('your query...')
.then(function(dbResponse) {
// Parse the response to the format you want then...
res.send(result);
})
.catch(function(error) {
// Handle error
res.send(error.message);
});
#spdev : I saw 1 of your comments about you being worried about how Node actually knows who to reply the response to, especially when there are multiple requests.
This is a very good question, and to be honest with you - I don't know much about it as well.
In short the answer is yes, Node somehow handles this by creating a corresponding ServerResponse object when a HTTP request comes through. This object seems to have some smartness to tell the Nodejs network stack how to route itself back to the caller when it gets parsed as data packets.
I tried Googling a bit for an answer but didn't got too far. I hope the ServerResponseObject documentation can provide more insight for you. Share with me if you got an answer thanks!
https://nodejs.org/api/all.html#http_class_http_serverresponse
Try below code.
router.get('/state', function(req, res){
var result = dbServer.makeDBCall(function(err,result){
if(!err) {
res.send(result);
}
});
}
Hope this Help.
The dbServer.makeDBCall(); must have a callback that runs when the statement completes executing.
Something like -
dbServer.makeDBCall({query: 'args'}, function(err, result){
if (err) // handle error
res.send(result);
})
You return the response from db from that callback function.
Learn more about callback from here-
nodeJs callbacks simple example
https://docs.nodejitsu.com/articles/getting-started/control-flow/what-are-callbacks/

Node.js - process millions of http post items without blocking

Using node.js, what is the best way to process a million items in an HTTP post request without blocking the server? My only guess is some sort of message queue, but I really have no idea.
You would want to use a lib like async.js to create non-blocking loops.
https://github.com/caolan/async
var async = require("async");
async.each(yourArrayOfThings, function(oneItem, callback) {
// do something
// ...
return callback(null);
}, function(err) {
// if any of the callbacks returned an error, err would equal that error
});
Give some more information on what your processing needs are, if this is not an applicable solution for you.

Why can't we do multiple response.send in Express.js?

3 years ago I could do multiple res.send in express.js.
even write a setTimeout to show up a live output.
response.send('<script class="jsbin" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>');
response.send('<html><body><input id="text_box" /><button>submit</button></body></html>');
var initJs = function() {
$('.button').click(function() {
$.post('/input', { input: $('#text_box').val() }, function() { alert('has send');});
});
}
response.send('<script>' + initJs + '</script>');
Now it will throw:
Error: Can't set headers after they are sent
I know nodejs and express have updated. Why can't do that now? Any other idea?
Found the solution but res.write is not in api reference http://expressjs.com/4x/api.html
Maybe you need: response.write
response.write("foo");
response.write("bar");
//...
response.end()
res.send implicitly calls res.write followed by res.end. If you call res.send multiple times, it will work the first time. However, since the first res.send call ends the response, you cannot add anything to the response.
response.send sends an entire HTTP response to the client, including headers and content, which is why you are unable to call it multiple times. In fact, it even ends the response, so there is no need to call response.end explicitly when using response.send.
It appears to me that you are attempting to use send like a buffer: writing to it with the intention to flush later. This is not how the method works, however; you need to build up your response in code and then make a single send call.
Unfortunately, I cannot speak to why or when this change was made, but I know that it has been like this at least since Express 3.
res.write immediately sends bytes to the client
I just wanted to make this point about res.write clearer.
It does not build up the reply and wait for res.end(). It just sends right away.
This means that the first time you call it, it will send the HTTP reply headers including the status in order to have a meaningful response. So if you want to set a status or custom header, you have to do it before that first call, much like with send().
Note that write() is not what you usually want to do in a simple web application. The browser getting the reply little by little increases the complexity of things, so you will only want to do it it if it is really needed.
Use res.locals to build the reply across middleware
This was my original use case, and res.locals fits well. I can just store data in an Array there, and then on the very last middleware join them up and do a final send to send everything at once, something like:
async (err, req, res, next) => {
res.locals.msg = ['Custom handler']
next(err)
},
async (err, req, res, next) => {
res.locals.msg.push('Custom handler 2')
res.status(500).send(res.locals.msg.join('\n'))
}

Resources