agentkeepalive

repository·master·Indexed 20 days ago

https://github.com/node-modules/agentkeepalive

An enhancement for Node.js http.Agent providing improved keep-alive management, socket timeouts (free and active), and TTL for active sockets to prevent socket leaks and improve performance. It includes HttpAgent and HttpsAgent classes that offer higher transaction rates and lower response times compared to the normal Node.js agent, along with tools for monitoring agent status via getCurrentStatus().

Tokens
3.3K
Snippets
11
Records
13
Agent score
70%

What's inside agentkeepalive

  1. Handle ECONNRESET retries using req.reusedSocket

    master

    When a server closes a connection during a keep-alive race, the client may throw an ECONNRESET error. agentkeepalive implements req.reusedSocket, which allows you to detect if the request was sent through a reused socket. If req.reusedSocket is true and the error is ECONNRESET, you can safely retry the request.

    const http = require('http');
    const HttpAgent = require('agentkeepalive').HttpAgent;
    const agent = new HttpAgent();
    
    const req = http
      .get('http://localhost:3000', { agent }, (res) => {
        // ... handle response
      })
      .on('error', (err) => {
        // If the error happened on a reused socket, it's likely a keep-alive race
        if (req.reusedSocket && err.code === 'ECONNRESET') {
          // retry the request...
        }
      });
  2. Configure the Agent with options

    master

    When instantiating HttpAgent or HttpsAgent, you can pass an options object to tune socket behavior.

    Available Options:

    • keepAlive {Boolean}: Keep sockets in a pool for future requests. Defaults to true.
    • keepAliveMsecs {Number}: Initial delay for TCP Keep-Alive packets. Only relevant if keepAlive is true. Defaults to 1000.
    • freeSocketTimeout {Number}: Timeout for a free socket after inactivity (in ms). Defaults to 4000 (to avoid ECONNRESET). Only relevant if keepAlive is true.
    • timeout {Number}: Timeout for a working (active) socket after inactivity (in ms). Defaults to freeSocketTimeout * 2 (or 8000 if that is smaller).
    • maxSockets {Number}: Maximum sockets allowed per host. Defaults to Infinity.
    • maxFreeSockets {Number}: Maximum sockets to leave open in a free state per host. Only relevant if keepAlive is true. Defaults to 256.
    • socketActiveTTL {Number}: Sets the socket active time to live, even if it's in use. If not set, the socket is released only when it becomes free. Defaults to null.
    const HttpAgent = require('agentkeepalive').HttpAgent;
    
    const keepaliveAgent = new HttpAgent({
      maxSockets: 100,
      maxFreeSockets: 10,
      timeout: 60000, // active socket keepalive for 60 seconds
      freeSocketTimeout: 30000, // free socket keepalive for 30 seconds
    });
  3. Compare Keepalive Agent vs Normal Agent performance

    master

    The benchmark results demonstrate that using the agentkeepalive agent significantly improves transaction rates and reduces response times compared to a normal Node.js agent.

    In the provided benchmark environment (Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz, Node v0.8.9):

    • Keep alive agent (30 seconds): Achieved a transaction rate of 2020.20 trans/sec with a response time of 0.03 secs.
    • Normal agent: Achieved a transaction rate of 1289.49 trans/sec with a response time of 0.05 secs.

    Key performance indicators show that the keepalive agent maintains higher concurrency and throughput by reusing sockets more effectively, resulting in fewer socket creations and lower latency distributions.

  4. Use HttpsAgent for HTTPS requests

    master

    For secure connections, use HttpsAgent from the agentkeepalive module and pass it to the agent option in your https.request configuration.

    const https = require('https');
    const HttpsAgent = require('agentkeepalive').HttpsAgent;
    
    const keepaliveAgent = new HttpsAgent();
    
    const options = {
      host: 'www.google.com',
      port: 443,
      path: '/search?q=nodejs',
      method: 'GET',
      agent: keepaliveAgent,
    };
    
    const req = https.request(options, res => {
      console.log('STATUS: ' + res.statusCode);
      res.on('data', chunk => {
        console.log('BODY: ' + chunk);
      });
    });
    
    req.on('error', e => {
      console.log('problem with request: ' + e.message);
    });
    
    req.end();
  5. Use HttpAgent for HTTP requests

    master

    To use agentkeepalive with standard HTTP requests, import HttpAgent and pass the instance to the agent property of your request options.

    const http = require('http');
    const HttpAgent = require('agentkeepalive').HttpAgent;
    
    const keepaliveAgent = new HttpAgent({
      maxSockets: 100,
      maxFreeSockets: 10,
      timeout: 60000,
      freeSocketTimeout: 30000,
    });
    
    const options = {
      host: 'cnodejs.org',
      port: 80,
      path: '/',
      method: 'GET',
      agent: keepaliveAgent,
    };
    
    const req = http.request(options, res => {
      console.log('STATUS: ' + res.statusCode);
      res.on('data', chunk => {
        console.log('BODY: ' + chunk);
      });
    });
    
    req.on('error', e => {
      console.log('problem with request: ' + e.message);
    });
    
    req.end();
  6. Monitor agent status with getCurrentStatus()

    master

    You can monitor the internal state of an agent using agent.getCurrentStatus(). This returns an object containing socket and request counters. You can check the agent.statusChanged getter to see if counters have changed since the last checkpoint.

    // Returns an object like:
    // {
    //   createSocketCount: 10,
    //   closeSocketCount: 5,
    //   timeoutSocketCount: 0,
    //   requestCount: 5,
    //   freeSockets: { 'localhost:57479:': 3 },
    //   sockets: { 'localhost:57479:': 5 },
    //   requests: {}
    // }
    const status = keepaliveAgent.getCurrentStatus();
    
    // Check if status has changed
    if (keepaliveAgent.statusChanged) {
      console.log('Agent status changed:', status);
    }
  7. Configure the Agent constructor options

    master

    The Agent class extends the native Node.js http.Agent and accepts an options object to manage keep-alive behavior and socket lifecycles.

    Key Options:

    • keepAlive: Boolean. Defaults to true. Enables socket pooling.
    • freeSocketTimeout: Number (milliseconds). The time a socket can sit idle in the pool before being destroyed. Defaults to 4000ms. (Note: keepAliveTimeout and freeSocketKeepAliveTimeout are deprecated aliases for this).
    • timeout: Number (milliseconds). The inactivity timeout for active sockets. Defaults to Math.max(freeSocketTimeout * 2, 8000).
    • socketActiveTTL: Number (milliseconds). The maximum total lifetime of a socket from creation, regardless of activity. If set, sockets are destroyed once they reach this age.

    All time-based options support human-readable formats (e.g., '5s', '10m') via humanize-ms.

    const Agent = require('agentkeepalive');
    const agent = new Agent({
      keepAlive: true,
      freeSocketTimeout: 5000,
      timeout: 10000,
      socketActiveTTL: 60000
    });
  8. Deprecated Agent properties and migration

    master

    The following properties are deprecated and will log a warning to the console. You should migrate to the recommended options/properties:

    Deprecated PropertyRecommended Replacement
    options.keepAliveTimeoutoptions.freeSocketTimeout
    options.freeSocketKeepAliveTimeoutoptions.freeSocketTimeout
    agent.freeSocketKeepAliveTimeoutagent.options.freeSocketTimeout
    agent.timeoutagent.options.timeout
    agent.socketActiveTTLagent.options.socketActiveTTL
  9. Use HttpAgent and HttpsAgent from agentkeepalive

    master

    The agentkeepalive package provides HttpAgent and HttpsAgent classes, which are enhanced versions of Node.js's built-in http.Agent and https.Agent. These agents are designed to improve performance by managing socket keep-alive more effectively.

    To use the package, you can require the main export (which is HttpAgent) or access the specific classes via the named exports.

    const agentkeepalive = require('agentkeepalive');
    
    // Accessing via main export (HttpAgent)
    const HttpAgent = agentkeepalive;
    
    // Accessing via named exports
    const { HttpAgent: MyHttpAgent, HttpsAgent } = agentkeepalive;
    
    // Usage example (conceptual):
    // const agent = new HttpAgent({ keepAlive: true, maxSockets: 100 });
  10. Use HttpsAgent for HTTPS keep-alive

    master

    The HttpsAgent class provides keep-alive functionality specifically for HTTPS requests. It extends the base HttpAgent and is designed to be used as the agent option in Node.js https.request() or https.get() calls. It manages a session cache for TLS sessions to optimize connection reuse.

    Key configuration properties inherited or defined:

    • maxCachedSessions: The maximum number of TLS sessions to cache. Defaults to 100 if not specified in the options object.
    const https = require('https');
    const HttpsAgent = require('agentkeepalive/https_agent');
    
    const agent = new HttpsAgent({
      maxSockets: 10,
      maxFreeSockets: 5,
      maxCachedSessions: 50
    });
    
    const options = {
      hostname: 'example.com',
      port: 443,
      path: '/',
      method: 'GET',
      agent: agent
    };
    
    https.request(options, (res) => {
      // ...
    }).end();
  11. Monitor Agent status and socket metrics

    master

    You can monitor the health and activity of the Agent using two primary methods:

    1. agent.getCurrentStatus(): Returns an object containing detailed counters for socket lifecycle events and current pool sizes.
    2. agent.statusChanged (getter): A boolean property that returns true if any of the internal counters (creation, errors, closures, timeouts, or requests) have changed since the last check.

    Status Object Fields:

    • createSocketCount: Total sockets created.
    • createSocketErrorCount: Total socket creation failures.
    • closeSocketCount: Total sockets closed.
    • errorSocketCount: Total socket errors encountered.
    • timeoutSocketCount: Total sockets that timed out.
    • requestCount: Total number of requests processed.
    • freeSockets: A summary of currently idle sockets.
    • sockets: A summary of all currently managed sockets.
    • requests: A summary of pending requests.
    const agent = new Agent();
    
    // Check if anything has changed since last time
    if (agent.statusChanged) {
      console.log('Agent metrics updated:', agent.getCurrentStatus());
    }