added feature detection for native KeepAlive support in 0.11

This commit is contained in:
Spencer Alger
2014-07-10 18:06:14 -07:00
parent a9f8122063
commit e8144714a8
5 changed files with 87 additions and 46 deletions

View File

@ -72,7 +72,7 @@
"dependencies": {
"bluebird": "~1.2.4",
"chalk": "~0.4",
"forever-agent": "0.5.2",
"forever-agent": "~0.5.2",
"lodash-node": "~2.4"
},
"repository": {

View File

@ -0,0 +1,48 @@
var ForeverAgent = require('forever-agent');
var ForeverSSLAgent = require('forever-agent').SSL;
var NativeAgent = require('http').Agent;
var NativeSSLAgent = require('https').Agent;
var inherits = require('util').inherits;
var nativeKeepAlive = (function () {
var a = new NativeAgent();
return !!a.freeSockets;
}());
function WrapForeverAgent(opts) {
ForeverAgent.call(this, opts);
var _addRequest = this.addRequest;
this.addRequest = function (req, host, port) {
req.useChunkedEncodingByDefault = false;
_addRequest.call(this, req, host, port);
};
}
inherits(WrapForeverAgent, ForeverAgent);
function WrapForeverSSLAgent(opts) {
ForeverSSLAgent.call(this, opts);
var _addRequest = this.addRequest;
this.addRequest = function (req, host, port) {
req.useChunkedEncodingByDefault = false;
_addRequest.call(this, req, host, port);
};
}
inherits(WrapForeverSSLAgent, ForeverSSLAgent);
function WrapNativeAgent(opts) { NativeAgent.call(this, opts); }
inherits(WrapNativeAgent, NativeAgent);
function WrapNativeSSLAgent(opts) { NativeSSLAgent.call(this, opts); }
inherits(WrapNativeSSLAgent, NativeSSLAgent);
if (nativeKeepAlive) {
module.exports = WrapNativeAgent;
module.exports.SSL = WrapNativeSSLAgent;
} else {
module.exports = WrapForeverAgent;
module.exports.SSL = WrapForeverSSLAgent;
}
module.exports.supportsNativeKeepAlive = nativeKeepAlive;

View File

@ -1,17 +0,0 @@
module.exports = CustomForeverAgent;
var ForeverAgent = require('forever-agent');
var inherits = require('util').inherits;
function CustomForeverAgent(opts) {
ForeverAgent.call(this, opts);
}
inherits(CustomForeverAgent, ForeverAgent);
CustomForeverAgent.prototype.addRequest = function (req, host, port) {
// force this, so that requests will always use the connection pool
req.useChunkedEncodingByDefault = false;
ForeverAgent.prototype.addRequest.call(this, req, host, port);
};
CustomForeverAgent.SSL = ForeverAgent.SSL;

View File

@ -14,7 +14,7 @@ var handles = {
};
var _ = require('../utils');
var qs = require('querystring');
var ForeverAgent = require('./_custom_forever_agent');
var ForeverAgent = require('./_custom_agent');
var ConnectionAbstract = require('../connection');
/**

View File

@ -1,12 +1,13 @@
describe('Http Connector', function () {
var _ = require('lodash-node');
var expect = require('expect.js');
var nock = require('nock');
var sinon = require('sinon');
var util = require('util');
var ForeverAgent = require('forever-agent');
var http = require('http');
var https = require('https');
var CustomAgent = require('../../../src/lib/connectors/_custom_agent');
var Host = require('../../../src/lib/host');
var errors = require('../../../src/lib/errors');
@ -161,7 +162,7 @@ describe('Http Connector', function () {
con.request({}, function () {
expect(http.request.callCount).to.be(1);
expect(https.request.callCount).to.be(0);
expect(http.request.lastCall.args[0].agent).to.be.a(ForeverAgent);
expect(http.request.lastCall.args[0].agent).to.be.a(CustomAgent);
done();
});
});
@ -171,7 +172,7 @@ describe('Http Connector', function () {
con.request({}, function () {
expect(http.request.callCount).to.be(0);
expect(https.request.callCount).to.be(1);
expect(https.request.lastCall.args[0].agent).to.be.a(ForeverAgent.SSL);
expect(https.request.lastCall.args[0].agent).to.be.a(CustomAgent.SSL);
done();
});
});
@ -357,38 +358,47 @@ describe('Http Connector', function () {
});
describe('Connection cleanup', function () {
// skip these tests if native keep alive requests are supported
if (CustomAgent.supportsNativeKeepAlive) {
return;
}
it('destroys any connections created', function (done) {
this.timeout(null);
var cp = require('child_process');
var path = require('path');
var fixtures = path.join(__dirname, '../../fixtures/');
var fixture = _.partial(path.join, __dirname, '../../fixtures');
var timeout; // start the timeout once we hear back from the client
var server = cp.fork(fixtures + 'keepalive_server.js');
var client = cp.fork(fixtures + 'keepalive.js');
var server = cp.fork(fixture('keepalive_server.js'))
.on('message', function (port) {
console.log('server sent port number', port);
client.send(port);
})
.once('exit', function () {
console.log('server closed');
});
server.on('message', function (port) {
client.send(port);
});
var client = cp.fork(fixture('keepalive.js'))
.on('message', function (output) {
console.log('client sent output', output);
expect(output).to.have.property('remaining', 0);
expect(output).to.have.property('timeouts', 0);
server.kill('SIGKILL');
if (client.connected) {
client.disconnect();
}
client.on('message', function (output) {
expect(output).to.have.property('remaining', 0);
expect(output).to.have.property('timeouts', 0);
server.kill('SIGKILL');
if (client.connected) {
client.disconnect();
}
timeout = setTimeout(function () {
client.removeListener('exit');
done(new Error('process should have closed by now'));
}, 2000);
});
client.on('exit', function () {
clearTimeout(timeout);
done();
});
timeout = setTimeout(function () {
client.removeListener('exit');
done(new Error('process should have closed by now'));
}, 2000);
})
.on('exit', function () {
console.log('client closed');
clearTimeout(timeout);
done();
});
});
it('properly removes all elements from the socket', function () {