CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-forever-agent

HTTP Agent that keeps socket connections alive between keep-alive requests

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

Forever Agent

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.

Package Information

  • Package Name: forever-agent
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install forever-agent

Core Imports

const ForeverAgent = require('forever-agent');

ES6 imports:

import ForeverAgent from 'forever-agent';

Basic Usage

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();

Architecture

Forever Agent extends Node.js's built-in HTTP Agent with the following key components:

  • Socket Pool Management: Maintains both active and idle socket pools per host/port combination
  • Connection Reuse: Intelligently reuses idle sockets for new requests when possible
  • Configurable Limits: Supports both maximum socket limits (like standard Agent) and minimum idle socket thresholds
  • SSL Support: Separate SSL agent class for HTTPS connections using TLS
  • Error Handling: Automatic cleanup of failed idle sockets with proper event handling

Capabilities

HTTP Agent Constructor

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;

SSL Agent Constructor

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;

Request Management

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);

Socket Management

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);

Instance Properties

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

Types

/**
 * 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[];
}

Error Handling

Forever Agent includes automatic error handling for idle sockets:

  • Idle Socket Errors: Automatically destroys sockets that encounter errors while idle
  • Pool Cleanup: Removes failed sockets from pools and queues replacement connections when needed
  • Connection Management: Handles socket lifecycle events to maintain pool integrity
// 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 management

Usage Examples

Basic HTTP Client

const 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');
});

HTTPS with SSL Agent

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();

Integration with Request Libraries

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');
  }
});

docs

index.md

tile.json