• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# agentkeepalive
2
3[![NPM version][npm-image]][npm-url]
4[![build status][travis-image]][travis-url]
5[![Appveyor status][appveyor-image]][appveyor-url]
6[![Test coverage][codecov-image]][codecov-url]
7[![David deps][david-image]][david-url]
8[![Known Vulnerabilities][snyk-image]][snyk-url]
9[![npm download][download-image]][download-url]
10
11[npm-image]: https://img.shields.io/npm/v/agentkeepalive.svg?style=flat
12[npm-url]: https://npmjs.org/package/agentkeepalive
13[travis-image]: https://img.shields.io/travis/node-modules/agentkeepalive.svg?style=flat
14[travis-url]: https://travis-ci.org/node-modules/agentkeepalive
15[appveyor-image]: https://ci.appveyor.com/api/projects/status/k7ct4s47di6m5uy2?svg=true
16[appveyor-url]: https://ci.appveyor.com/project/fengmk2/agentkeepalive
17[codecov-image]: https://codecov.io/gh/node-modules/agentkeepalive/branch/master/graph/badge.svg
18[codecov-url]: https://codecov.io/gh/node-modules/agentkeepalive
19[david-image]: https://img.shields.io/david/node-modules/agentkeepalive.svg?style=flat
20[david-url]: https://david-dm.org/node-modules/agentkeepalive
21[snyk-image]: https://snyk.io/test/npm/agentkeepalive/badge.svg?style=flat-square
22[snyk-url]: https://snyk.io/test/npm/agentkeepalive
23[download-image]: https://img.shields.io/npm/dm/agentkeepalive.svg?style=flat-square
24[download-url]: https://npmjs.org/package/agentkeepalive
25
26The Node.js's missing `keep alive` `http.Agent`. Support `http` and `https`.
27
28## What's different from original `http.Agent`?
29
30- `keepAlive=true` by default
31- Disable Nagle's algorithm: `socket.setNoDelay(true)`
32- Add free socket timeout: avoid long time inactivity socket leak in the free-sockets queue.
33- Add active socket timeout: avoid long time inactivity socket leak in the active-sockets queue.
34
35## Install
36
37```bash
38$ npm install agentkeepalive --save
39```
40
41## new Agent([options])
42
43* `options` {Object} Set of configurable options to set on the agent.
44  Can have the following fields:
45  * `keepAlive` {Boolean} Keep sockets around in a pool to be used by
46    other requests in the future. Default = `true`.
47  * `keepAliveMsecs` {Number} When using the keepAlive option, specifies the initial delay
48    for TCP Keep-Alive packets. Ignored when the keepAlive option is false or undefined. Defaults to 1000.
49    Default = `1000`.  Only relevant if `keepAlive` is set to `true`.
50  * `freeSocketKeepAliveTimeout`: {Number} Sets the free socket to timeout
51    after `freeSocketKeepAliveTimeout` milliseconds of inactivity on the free socket.
52    Default is `15000`.
53    Only relevant if `keepAlive` is set to `true`.
54  * `timeout`: {Number} Sets the working socket to timeout
55    after `timeout` milliseconds of inactivity on the working socket.
56    Default is `freeSocketKeepAliveTimeout * 2`.
57  * `maxSockets` {Number} Maximum number of sockets to allow per
58    host. Default = `Infinity`.
59  * `maxFreeSockets` {Number} Maximum number of sockets (per host) to leave open
60    in a free state. Only relevant if `keepAlive` is set to `true`.
61    Default = `256`.
62  * `socketActiveTTL` {Number} Sets the socket active time to live, even if it's in use.
63    If not setted the behaviour continues the same (the socket will be released only when free)
64    Default = `null`.
65
66## Usage
67
68```js
69const http = require('http');
70const Agent = require('agentkeepalive');
71
72const keepaliveAgent = new Agent({
73  maxSockets: 100,
74  maxFreeSockets: 10,
75  timeout: 60000,
76  freeSocketKeepAliveTimeout: 30000, // free socket keepalive for 30 seconds
77});
78
79const options = {
80  host: 'cnodejs.org',
81  port: 80,
82  path: '/',
83  method: 'GET',
84  agent: keepaliveAgent,
85};
86
87const req = http.request(options, res => {
88  console.log('STATUS: ' + res.statusCode);
89  console.log('HEADERS: ' + JSON.stringify(res.headers));
90  res.setEncoding('utf8');
91  res.on('data', function (chunk) {
92    console.log('BODY: ' + chunk);
93  });
94});
95req.on('error', e => {
96  console.log('problem with request: ' + e.message);
97});
98req.end();
99
100setTimeout(() => {
101  if (keepaliveAgent.statusChanged) {
102    console.log('[%s] agent status changed: %j', Date(), keepaliveAgent.getCurrentStatus());
103  }
104}, 2000);
105
106```
107
108### `getter agent.statusChanged`
109
110counters have change or not after last checkpoint.
111
112### `agent.getCurrentStatus()`
113
114`agent.getCurrentStatus()` will return a object to show the status of this agent:
115
116```js
117{
118  createSocketCount: 10,
119  closeSocketCount: 5,
120  timeoutSocketCount: 0,
121  requestCount: 5,
122  freeSockets: { 'localhost:57479:': 3 },
123  sockets: { 'localhost:57479:': 5 },
124  requests: {}
125}
126```
127
128### Support `https`
129
130```js
131const https = require('https');
132const HttpsAgent = require('agentkeepalive').HttpsAgent;
133
134const keepaliveAgent = new HttpsAgent();
135// https://www.google.com/search?q=nodejs&sugexp=chrome,mod=12&sourceid=chrome&ie=UTF-8
136const options = {
137  host: 'www.google.com',
138  port: 443,
139  path: '/search?q=nodejs&sugexp=chrome,mod=12&sourceid=chrome&ie=UTF-8',
140  method: 'GET',
141  agent: keepaliveAgent,
142};
143
144const req = https.request(options, res => {
145  console.log('STATUS: ' + res.statusCode);
146  console.log('HEADERS: ' + JSON.stringify(res.headers));
147  res.setEncoding('utf8');
148  res.on('data', chunk => {
149    console.log('BODY: ' + chunk);
150  });
151});
152
153req.on('error', e => {
154  console.log('problem with request: ' + e.message);
155});
156req.end();
157
158setTimeout(() => {
159  console.log('agent status: %j', keepaliveAgent.getCurrentStatus());
160}, 2000);
161```
162
163## [Benchmark](https://github.com/node-modules/agentkeepalive/tree/master/benchmark)
164
165run the benchmark:
166
167```bash
168cd benchmark
169sh start.sh
170```
171
172Intel(R) Core(TM)2 Duo CPU     P8600  @ 2.40GHz
173
174node@v0.8.9
175
17650 maxSockets, 60 concurrent, 1000 requests per concurrent, 5ms delay
177
178Keep alive agent (30 seconds):
179
180```js
181Transactions:          60000 hits
182Availability:         100.00 %
183Elapsed time:          29.70 secs
184Data transferred:        14.88 MB
185Response time:            0.03 secs
186Transaction rate:      2020.20 trans/sec
187Throughput:           0.50 MB/sec
188Concurrency:           59.84
189Successful transactions:       60000
190Failed transactions:             0
191Longest transaction:          0.15
192Shortest transaction:         0.01
193```
194
195Normal agent:
196
197```js
198Transactions:          60000 hits
199Availability:         100.00 %
200Elapsed time:          46.53 secs
201Data transferred:        14.88 MB
202Response time:            0.05 secs
203Transaction rate:      1289.49 trans/sec
204Throughput:           0.32 MB/sec
205Concurrency:           59.81
206Successful transactions:       60000
207Failed transactions:             0
208Longest transaction:          0.45
209Shortest transaction:         0.00
210```
211
212Socket created:
213
214```
215[proxy.js:120000] keepalive, 50 created, 60000 requestFinished, 1200 req/socket, 0 requests, 0 sockets, 0 unusedSockets, 50 timeout
216{" <10ms":662," <15ms":17825," <20ms":20552," <30ms":17646," <40ms":2315," <50ms":567," <100ms":377," <150ms":56," <200ms":0," >=200ms+":0}
217----------------------------------------------------------------
218[proxy.js:120000] normal   , 53866 created, 84260 requestFinished, 1.56 req/socket, 0 requests, 0 sockets
219{" <10ms":75," <15ms":1112," <20ms":10947," <30ms":32130," <40ms":8228," <50ms":3002," <100ms":4274," <150ms":181," <200ms":18," >=200ms+":33}
220```
221
222## License
223
224```
225(The MIT License)
226
227Copyright(c) node-modules and other contributors.
228Copyright(c) 2012 - 2015 fengmk2 <fengmk2@gmail.com>
229
230Permission is hereby granted, free of charge, to any person obtaining
231a copy of this software and associated documentation files (the
232'Software'), to deal in the Software without restriction, including
233without limitation the rights to use, copy, modify, merge, publish,
234distribute, sublicense, and/or sell copies of the Software, and to
235permit persons to whom the Software is furnished to do so, subject to
236the following conditions:
237
238The above copyright notice and this permission notice shall be
239included in all copies or substantial portions of the Software.
240
241THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
242EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
243MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
244IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
245CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
246TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
247SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
248```
249