-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This changeset allows reusing a http agent which results in using a request pool for requests.
- Loading branch information
1 parent
07eedd7
commit a035cd5
Showing
6 changed files
with
181 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* This module limits the created of http.Agent instances to only one that | ||
* allows connection pooling and another one that does not. | ||
* The agents will be created on demand the first time and then the instances | ||
* will be returned on subsequent calls to the getAgent method. | ||
*/ | ||
const http = require('http'); | ||
const https = require('https'); | ||
|
||
const DEFAULT_KEEP_ALIVE_MSECS = 60000; | ||
const DEFAULT_KEEP_ALIVE_MAX_SOCKETS = 32; | ||
const DEFAULT_KEEP_ALIVE_MAX_FREE_SOCKETS = 32; | ||
|
||
let keepAliveAgent; | ||
let defaultAgent; | ||
|
||
/** | ||
* Retuns a new instance of the http.Agent | ||
* @param {Boolean} isSecure is https? | ||
* @param {Object} [options] can contain | ||
* - options.keepAlive {Boolean} | ||
* - options.keepAliveMsecs {Integer} | ||
* - options.maxSockets {Integer} | ||
* - options.maxFreeSockets {Integer} | ||
* | ||
* @returns {http.Agent} Agent | ||
*/ | ||
function createAgent(isSecure, options = {}) { | ||
return new (isSecure ? https : http).Agent(options); | ||
} | ||
|
||
/** | ||
* Returns an instance of the 'keep-alive' http.Agent that _ALLOWS_ connection | ||
* pooling | ||
* It will create a new instance only the first time is invoked | ||
* @param {Boolean} isSecure is https? | ||
* | ||
* @returns {http.Agent} Agent | ||
*/ | ||
function getKeepAliveAgent(isSecure) { | ||
if (!keepAliveAgent) { | ||
keepAliveAgent = createAgent(isSecure, { | ||
keepAlive: true, | ||
keepAliveMsecs: DEFAULT_KEEP_ALIVE_MSECS, | ||
maxSockets: DEFAULT_KEEP_ALIVE_MAX_SOCKETS, | ||
maxFreeSockets: DEFAULT_KEEP_ALIVE_MAX_FREE_SOCKETS | ||
}); | ||
} | ||
|
||
return keepAliveAgent; | ||
} | ||
|
||
/** | ||
* Returns an instance of the default http.Agent that _DOES_NOT_ allow | ||
* connection pooling | ||
* It will create a new instance only the first time is invoked | ||
* @param {Boolean} isSecure is https? | ||
* | ||
* @returns {http.Agent} Agent | ||
*/ | ||
function getDefaultAgent(isSecure) { | ||
if (!defaultAgent) { | ||
defaultAgent = createAgent(isSecure); | ||
} | ||
|
||
return defaultAgent; | ||
} | ||
|
||
module.exports = { | ||
/** | ||
* Returns the appropriate agent depending on the specified params | ||
* @param {Boolean} isSecure is https? | ||
* @param {Bollean} allowPooling should we keep connection alive? | ||
* | ||
* @returns {http.Agent} Agent | ||
*/ | ||
getAgent: function (isSecure, allowPooling) { | ||
return allowPooling ? | ||
getKeepAliveAgent(isSecure) : | ||
getDefaultAgent(isSecure); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/*eslint no-magic-numbers: 0*/ | ||
/*eslint no-unused-expressions: 0*/ | ||
const { expect } = require('chai'); | ||
const httpAgent = require('../../lib/http-agent'); | ||
|
||
describe('http-agent', () => { | ||
describe('connection pooling', () => { | ||
describe('https', () => { | ||
it('should allow connection pooling', () => { | ||
const isSecure = true; | ||
const allowPooling = true; | ||
const agent = httpAgent.getAgent(isSecure, allowPooling); | ||
|
||
// agent must allow connection pooling | ||
expect(agent.options.keepAlive).to.be.true; | ||
}); | ||
|
||
it('should _not_ allow connection pooling', () => { | ||
const isSecure = true; | ||
const allowPooling = false; | ||
const agent = httpAgent.getAgent(isSecure, allowPooling); | ||
|
||
// if connection pooling is disabled then the keep alive field | ||
// will not exist | ||
expect(agent.options.keepAlive).to.be.undefined; | ||
}); | ||
}); | ||
|
||
describe('http', () => { | ||
it('should allow connection pooling', () => { | ||
const isSecure = false; | ||
const allowPooling = true; | ||
const agent = httpAgent.getAgent(isSecure, allowPooling); | ||
|
||
// agent must allow connection pooling | ||
expect(agent.options.keepAlive).to.be.true; | ||
}); | ||
|
||
it('should _not_ allow connection pooling', () => { | ||
const isSecure = false; | ||
const allowPooling = false; | ||
const agent = httpAgent.getAgent(isSecure, allowPooling); | ||
|
||
// if connection pooling is disabled then the keep alive field | ||
// will not exist | ||
expect(agent.options.keepAlive).to.be.undefined; | ||
}); | ||
}); | ||
}); | ||
|
||
describe('agents should be reused', () => { | ||
it('should reuse https agent', () => { | ||
const maxIterations = 5; | ||
const isSecure = true; | ||
const allowPooling = true; | ||
// get agent that should be reused | ||
const agent = httpAgent.getAgent(isSecure, allowPooling); | ||
|
||
// set a dummy param so that we can verify that next time the same | ||
// agent is returned. | ||
agent.foo = true; | ||
|
||
for (let i = 0; i < maxIterations; i++) { | ||
let fooAgent = httpAgent.getAgent(isSecure, allowPooling); | ||
expect(fooAgent.foo).to.be.true; | ||
} | ||
|
||
}); | ||
|
||
it('should reuse http agent', () => { | ||
const maxIterations = 5; | ||
const isSecure = false; | ||
const allowPooling = true; | ||
|
||
// get agent that should be reused | ||
const agent = httpAgent.getAgent(isSecure, allowPooling); | ||
// set a dummy param so that we can verify that next time the same | ||
// agent is returned. | ||
agent.foo = true; | ||
|
||
for (let i = 0; i < maxIterations; i++) { | ||
let fooAgent = httpAgent.getAgent(isSecure, allowPooling); | ||
expect(fooAgent.foo).to.be.true; | ||
} | ||
}); | ||
}); | ||
}); |