agent.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * refer:
  3. * * @atimb "Real keep-alive HTTP agent": https://gist.github.com/2963672
  4. * * https://github.com/joyent/node/blob/master/lib/http.js
  5. * * https://github.com/joyent/node/blob/master/lib/https.js
  6. * * https://github.com/joyent/node/blob/master/lib/_http_agent.js
  7. *
  8. * Copyright(c) 2012 - 2014 fengmk2 <fengmk2@gmail.com>
  9. * Copyright(c) node-modules
  10. * MIT Licensed
  11. */
  12. 'use strict';
  13. /**
  14. * Module dependencies.
  15. */
  16. var https = require('https');
  17. var utils = require('./utils');
  18. var OriginalAgent = require('./_http_agent').Agent;
  19. var OriginalHttpsAgent = https.Agent;
  20. module.exports = Agent;
  21. function Agent(options) {
  22. if (!(this instanceof Agent)) {
  23. return new Agent(options);
  24. }
  25. options = options || {};
  26. options.keepAlive = options.keepAlive !== false;
  27. // default is keep-alive and 15s free socket timeout
  28. if (options.keepAliveTimeout === undefined) {
  29. options.keepAliveTimeout = 15000;
  30. }
  31. // default timeout is double keepalive timeout
  32. if (options.timeout === undefined) {
  33. options.timeout = options.keepAliveTimeout * 2;
  34. }
  35. OriginalAgent.call(this, options);
  36. var self = this;
  37. self.createSocketCount = 0;
  38. self.closeSocketCount = 0;
  39. // socket error event count
  40. self.errorSocketCount = 0;
  41. self.requestCount = 0;
  42. self.timeoutSocketCount = 0;
  43. self.on('free', function () {
  44. self.requestCount++;
  45. });
  46. self.on('timeout', function () {
  47. self.timeoutSocketCount++;
  48. });
  49. self.on('close', function () {
  50. self.closeSocketCount++;
  51. });
  52. self.on('error', function () {
  53. self.errorSocketCount++;
  54. });
  55. }
  56. utils.inherits(Agent, OriginalAgent);
  57. Agent.prototype.createSocket = function (req, options) {
  58. var socket = OriginalAgent.prototype.createSocket.call(this, req, options);
  59. if (this.keepAlive) {
  60. // Disable Nagle's algorithm: http://blog.caustik.com/2012/04/08/scaling-node-js-to-100k-concurrent-connections/
  61. // http://fengmk2.com/benchmark/nagle-algorithm-delayed-ack-mock.html
  62. socket.setNoDelay(true);
  63. }
  64. this.createSocketCount++;
  65. return socket;
  66. };
  67. Agent.prototype.getCurrentStatus = function () {
  68. return {
  69. createSocketCount: this.createSocketCount,
  70. closeSocketCount: this.closeSocketCount,
  71. errorSocketCount: this.errorSocketCount,
  72. timeoutSocketCount: this.timeoutSocketCount,
  73. requestCount: this.requestCount,
  74. freeSockets: inspect(this.freeSockets),
  75. sockets: inspect(this.sockets),
  76. requests: inspect(this.requests)
  77. };
  78. };
  79. function inspect(obj) {
  80. var res = {};
  81. for (var key in obj) {
  82. res[key] = obj[key].length;
  83. }
  84. return res;
  85. }