HTTP Agent that keeps socket connections alive between keep-alive requests
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Forever Agent is an HTTP Agent implementation that maintains persistent socket connections between keep-alive requests. It extends Node.js's built-in HTTP Agent with intelligent socket pooling that maintains a configurable minimum number of idle sockets per host/port combination, optimizing network performance by reusing existing connections rather than creating new ones for each request.
npm install forever-agentconst ForeverAgent = require('forever-agent');ES6 imports:
import ForeverAgent from 'forever-agent';const ForeverAgent = require('forever-agent');
const http = require('http');
// Create HTTP agent with persistent connections
const agent = new ForeverAgent({
maxSockets: 10, // Maximum sockets per host
minSockets: 5 // Minimum idle sockets to maintain
});
// Create HTTPS agent for SSL connections
const httpsAgent = new ForeverAgent.SSL({
maxSockets: 10,
minSockets: 3
});
// Use with http.request
const options = {
hostname: 'example.com',
port: 80,
path: '/api/data',
method: 'GET',
agent: agent // Use the forever agent
};
const req = http.request(options, (res) => {
console.log(`Status: ${res.statusCode}`);
res.on('data', (chunk) => {
console.log(chunk.toString());
});
});
req.end();Forever Agent extends Node.js's built-in HTTP Agent with the following key components:
Creates a new Forever Agent instance for HTTP connections.
/**
* Creates a Forever Agent for HTTP connections with persistent socket pooling
* @param {Object} options - Configuration options
* @param {number} options.maxSockets - Maximum sockets per host (default: Agent.defaultMaxSockets)
* @param {number} options.minSockets - Minimum idle sockets per host (default: ForeverAgent.defaultMinSockets = 5)
* @returns {ForeverAgent} New agent instance
*/
function ForeverAgent(options);
// Static property
ForeverAgent.defaultMinSockets = 5;Creates a new Forever Agent instance for HTTPS connections.
/**
* Creates a Forever Agent for HTTPS connections with persistent socket pooling
* @param {Object} options - Configuration options (same as ForeverAgent plus TLS options)
* @returns {ForeverAgentSSL} New SSL agent instance
*/
function ForeverAgentSSL(options);
// Access via main export
ForeverAgent.SSL = ForeverAgentSSL;Adds HTTP requests to the agent with intelligent socket reuse.
/**
* Adds a request to the agent, reusing idle sockets when possible
* @param {http.ClientRequest} req - HTTP request object
* @param {string|Object} host - Hostname string or options object with host/port
* @param {number} port - Port number (if host is string)
*/
ForeverAgent.prototype.addRequest = function(req, host, port);
/**
* Adds a request without socket reuse (fallback to standard Agent behavior)
* @param {http.ClientRequest} req - HTTP request object
* @param {string|Object} host - Hostname string or options object
* @param {number} port - Port number (if host is string)
*/
ForeverAgent.prototype.addRequestNoreuse = function(req, host, port);Manages socket lifecycle and pool maintenance.
/**
* Removes a socket from the agent pools and handles cleanup
* @param {net.Socket} socket - Socket to remove
* @param {string} name - Connection name
* @param {string} host - Hostname
* @param {number} port - Port number
*/
ForeverAgent.prototype.removeSocket = function(socket, name, host, port);
/**
* Creates a new connection (HTTP)
* @param {number|Object} port - Port number or options object
* @param {string|Object} host - Hostname or options object
* @param {Object} options - Connection options
* @returns {net.Socket} New socket connection
*/
ForeverAgent.prototype.createConnection = function(port, host, options);
/**
* Creates a new SSL/TLS connection (HTTPS)
* @param {number|Object} port - Port number or options object
* @param {string|Object} host - Hostname or options object
* @param {Object} options - TLS connection options
* @returns {tls.TLSSocket} New TLS socket connection
*/
ForeverAgentSSL.prototype.createConnection = function(port, host, options);Agent configuration and internal state management.
// Configuration properties
agent.options; // Object - Configuration options passed to constructor
agent.maxSockets; // number - Maximum sockets per host
agent.minSockets; // number - Minimum idle sockets per host
// Internal state (read-only access)
agent.requests; // Object - Pending requests by connection name
agent.sockets; // Object - Active sockets by connection name
agent.freeSockets; // Object - Available idle sockets by connection name/**
* Configuration options for ForeverAgent
*/
interface AgentOptions {
maxSockets?: number; // Maximum sockets per host (inherited from http.Agent)
minSockets?: number; // Minimum idle sockets per host (Forever Agent specific)
}
/**
* Connection name format: "host:port" or "host:port:localAddress:"
*/
type ConnectionName = string;
/**
* Socket pools organized by connection name
*/
interface SocketPools {
[connectionName: string]: net.Socket[];
}
/**
* Request queues organized by connection name
*/
interface RequestQueues {
[connectionName: string]: http.ClientRequest[];
}Forever Agent includes automatic error handling for idle sockets:
// Example with error handling
const agent = new ForeverAgent({ minSockets: 3 });
agent.on('free', (socket, host, port) => {
// Internal event - handled automatically by Forever Agent
// Manages socket reuse and idle pool maintenance
});
// Idle sockets automatically handle errors
// No manual error handling required for idle socket managementconst ForeverAgent = require('forever-agent');
const http = require('http');
const agent = new ForeverAgent({
maxSockets: 5,
minSockets: 2
});
function makeRequest(path) {
return new Promise((resolve, reject) => {
const req = http.request({
hostname: 'api.example.com',
port: 80,
path: path,
method: 'GET',
agent: agent
}, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => resolve(data));
});
req.on('error', reject);
req.end();
});
}
// Multiple requests will reuse connections
Promise.all([
makeRequest('/users'),
makeRequest('/posts'),
makeRequest('/comments')
]).then(results => {
console.log('All requests completed with connection reuse');
});const ForeverAgent = require('forever-agent');
const https = require('https');
const httpsAgent = new ForeverAgent.SSL({
maxSockets: 10,
minSockets: 3
});
const options = {
hostname: 'secure-api.example.com',
port: 443,
path: '/secure-data',
method: 'GET',
agent: httpsAgent
};
https.request(options, (res) => {
console.log(`Secure request status: ${res.statusCode}`);
res.on('data', (chunk) => {
process.stdout.write(chunk);
});
}).end();const ForeverAgent = require('forever-agent');
const request = require('request'); // or any HTTP client library
const agent = new ForeverAgent({
maxSockets: 8,
minSockets: 4
});
// Configure request library to use Forever Agent
const requestWithAgent = request.defaults({
agent: agent
});
requestWithAgent('http://example.com/api', (error, response, body) => {
if (!error && response.statusCode === 200) {
console.log('Request completed with persistent connection');
}
});