or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-forever-agent

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

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/forever-agent@0.6.x

To install, run

npx @tessl/cli install tessl/npm-forever-agent@0.6.0

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