Reputation: 24717
I'm reading IDs from a text file and making some RESTful requests. It works, but when all IDs have been run, the node app stays running.
main.js:
var fs = require('fs');
var http = require('http');
var ids = fs.readFileSync('test.txt', { encoding: 'utf8' });
ids = ids.split('\n');
var options = {
hostname: 'internalhost',
port: 80,
path: '',
method: 'DELETE'
};
for (var i = 0; i < ids.length; i++) {
options.path = '/thing/' + ids[i];
console.log('Deleting thing ' + ids[i]);
var req = http.request(options, function(res) {
console.log('Status: ' + res.statusCode);
});
req.on('error', function(e) {
console.log('Problem with request: ' + e.message);
});
req.end();
}
The requests are made successfully but after the last one, the app continues to run. I've tried adding res.end()
right after I print the response's status code, but then I get an error that res
doesn't have a method end
.
What's going on here?
Upvotes: 2
Views: 1066
Reputation: 144912
It appears you're suffering from a side-effect of HTTP keep-alives. Node does not exit when there are TCP connections open, and the HTTP Agent
leaves TCP connections open for an indefinite amount of time.
You've mentioned that keep-alives will be beneficial for you, so your options are limited.
Simply disabling the Agent
will result in keep-alives being disabled, so this isn't really an option.
You can manually manage and track your requests, and when all have been completed, call process.exit
. I don't like this, however, as it is a rather blunt instrument. If you have other async operations running (such as DB calls), you may accidentally end your app before those operations complete.
You can manually manage and track your requests. When all have been completed, you can loop through the Agent
instance's sockets
property and close all lingering sockets. (Warning: calling close
on an already closed socket throws.)
This is a much safer approach because other outstanding operations will be allowed to finish before the app exits.
You could upgrade to node ≥ 0.11.4. (Realistically, you'd probably want to wait until 0.12 stable is released.) The next node version has a greatly improved Agent
implementation that unref
s idle sockets kept in the Agent
's connection pool. In other words, node can exit if the only open TCP connections are those being held for reuse as a keep-alive connection.
You could also rip out the new Agent
implemention from the unstable branch and use it for your app's requests instead of the default Agent
provided by your version of node. (This is probably what I'd do.)
Upvotes: 3
Reputation: 30430
node will only terminate if there are no pending events to be handled. In this case I believe the connection is still open, so you can either destroy it manually by calling res.socket.end()
or res.destroy()
or as @ExplosionPills Suggested, just call process.exit
when all requests are done. You can use async
module to help you to achieve this.
Upvotes: 2