node-modules / agentkeepalive

Support keepalive http agent.
MIT License
579 stars 57 forks source link

process using https agent exits only after keepAliveTimeout #17

Closed vvo closed 9 years ago

vvo commented 9 years ago

After further testing using the new agentkeepalive@2 on node 0.10:

Http agent:

var http = require('http');
var Agent = require('agentkeepalive');

var keepaliveAgent = new Agent({
  keepAliveTimeout: 10000
});

var options = {
  host: 'www.example.com',
  path: '/',
  method: 'GET',
  agent: keepaliveAgent
};

var req = http.request(options, function (res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('received ' + chunk.length)
  });
  res.once('end', function() {
    console.log('end');
  });
}).end();
> time node http.js
STATUS: 200
HEADERS: {"accept-ranges":"bytes","cache-control":"max-age=604800","content-type":"text/html","date":"Fri, 03 Apr 2015 14:31:19 GMT","etag":"\"359670651\"","expires":"Fri, 10 Apr 2015 14:31:19 GMT","last-modified":"Fri, 09 Aug 2013 23:54:35 GMT","server":"ECS (mdw/1275)","x-cache":"HIT","x-ec-custom-error":"1","content-length":"1270"}
received 1270
end
node http.js  0.06s user 0.00s system 20% cpu 0.297 total

It takes 0.3 s to complete

Https agent:

var https = require('https');
var Agent = require('agentkeepalive').HttpsAgent;

var keepaliveAgent = new Agent({
  keepAliveTimeout: 10000
});

var options = {
  host: 'www.example.com',
  path: '/',
  method: 'GET',
  agent: keepaliveAgent
};

var req = https.request(options, function (res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('received ' + chunk.length)
  });
  res.once('end', function() {
    console.log('end');
  });
}).end();
> time node https.js
STATUS: 200
HEADERS: {"accept-ranges":"bytes","cache-control":"max-age=604800","content-type":"text/html","date":"Fri, 03 Apr 2015 14:31:22 GMT","etag":"\"359670651\"","expires":"Fri, 10 Apr 2015 14:31:22 GMT","last-modified":"Fri, 09 Aug 2013 23:54:35 GMT","server":"ECS (mdw/138F)","x-cache":"HIT","x-ec-custom-error":"1","content-length":"1270"}
received 1270
end
node https.js  0.06s user 0.00s system 0% cpu 10.541 total

It take 10.5s to complete

So the nodejs process only exits after the keepAlive timeout when using https agent.

fengmk2 commented 9 years ago

you use should agentkeepalive@0.2.x on node 0.10.x.

vvo commented 9 years ago

sorry. I am already using agentkeepalive 0.2

vvo commented 9 years ago

@fengmk2 any idea? Is this really a bug?

vvo commented 9 years ago

Hi, nice you have released agentkeepalive@2. This issue is still true, I tried it with latest agentkeepalive without success, process still hangs.

You can take the example code and it still hangs.

vvo commented 9 years ago

@fengmk2 I narrowed the test case and updated the issue description and title to be more precise.

It's not a "req.setTimeout" issue, only a keepAliveTimeout one.

Any hint?

fengmk2 commented 9 years ago

you should listen res end event to sum the time.

Http for Google search is response 302, and it not a keepAlive connection. HTTPS for Google search is response 200, and it was keepAlive and socket will be hold.

vvo commented 9 years ago

Ok @fengmk2 I updated the examples to use www.example.com, added the end event, double checked that we were dealing with the same amount of xfered content. Same behavior: https agent only exits after keepAliveTimeout

vvo commented 9 years ago

Seems like this is the default behavior using standard http.Agent in Node too. Makes sense: your process will not exits if there's remaining keepalived sockets. I guess it could be smarter than that like understanding that the only alive timers are keepalived connections and that all of them are terminated (response received) and thus destroy the agent.

But for now, you can just call agent.destroy().

Thanks.