PageRenderTime 28ms CodeModel.GetById 20ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/node_modules/request/forever.js

https://bitbucket.org/gagginaspinnata/todo-app-with-angularjs
JavaScript | 103 lines | 82 code | 13 blank | 8 comment | 23 complexity | fe32e57be097509d95316e64112d2b7e MD5 | raw file
Possible License(s): Apache-2.0, MIT
  1module.exports = ForeverAgent
  2ForeverAgent.SSL = ForeverAgentSSL
  3
  4var util = require('util')
  5  , Agent = require('http').Agent
  6  , net = require('net')
  7  , tls = require('tls')
  8  , AgentSSL = require('https').Agent
  9
 10function ForeverAgent(options) {
 11  var self = this
 12  self.options = options || {}
 13  self.requests = {}
 14  self.sockets = {}
 15  self.freeSockets = {}
 16  self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets
 17  self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets
 18  self.on('free', function(socket, host, port) {
 19    var name = host + ':' + port
 20    if (self.requests[name] && self.requests[name].length) {
 21      self.requests[name].shift().onSocket(socket)
 22    } else if (self.sockets[name].length < self.minSockets) {
 23      if (!self.freeSockets[name]) self.freeSockets[name] = []
 24      self.freeSockets[name].push(socket)
 25      
 26      // if an error happens while we don't use the socket anyway, meh, throw the socket away
 27      function onIdleError() {
 28        socket.destroy()
 29      }
 30      socket._onIdleError = onIdleError
 31      socket.on('error', onIdleError)
 32    } else {
 33      // If there are no pending requests just destroy the
 34      // socket and it will get removed from the pool. This
 35      // gets us out of timeout issues and allows us to
 36      // default to Connection:keep-alive.
 37      socket.destroy();
 38    }
 39  })
 40
 41}
 42util.inherits(ForeverAgent, Agent)
 43
 44ForeverAgent.defaultMinSockets = 5
 45
 46
 47ForeverAgent.prototype.createConnection = net.createConnection
 48ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest
 49ForeverAgent.prototype.addRequest = function(req, host, port) {
 50  var name = host + ':' + port
 51  if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) {
 52    var idleSocket = this.freeSockets[name].pop()
 53    idleSocket.removeListener('error', idleSocket._onIdleError)
 54    delete idleSocket._onIdleError
 55    req._reusedSocket = true
 56    req.onSocket(idleSocket)
 57  } else {
 58    this.addRequestNoreuse(req, host, port)
 59  }
 60}
 61
 62ForeverAgent.prototype.removeSocket = function(s, name, host, port) {
 63  if (this.sockets[name]) {
 64    var index = this.sockets[name].indexOf(s);
 65    if (index !== -1) {
 66      this.sockets[name].splice(index, 1);
 67    }
 68  } else if (this.sockets[name] && this.sockets[name].length === 0) {
 69    // don't leak
 70    delete this.sockets[name];
 71    delete this.requests[name];
 72  }
 73  
 74  if (this.freeSockets[name]) {
 75    var index = this.freeSockets[name].indexOf(s)
 76    if (index !== -1) {
 77      this.freeSockets[name].splice(index, 1)
 78      if (this.freeSockets[name].length === 0) {
 79        delete this.freeSockets[name]
 80      }
 81    }
 82  }
 83
 84  if (this.requests[name] && this.requests[name].length) {
 85    // If we have pending requests and a socket gets closed a new one
 86    // needs to be created to take over in the pool for the one that closed.
 87    this.createSocket(name, host, port).emit('free');
 88  }
 89}
 90
 91function ForeverAgentSSL (options) {
 92  ForeverAgent.call(this, options)
 93}
 94util.inherits(ForeverAgentSSL, ForeverAgent)
 95
 96ForeverAgentSSL.prototype.createConnection = createConnectionSSL
 97ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest
 98
 99function createConnectionSSL (port, host, options) {
100  options.port = port
101  options.host = host
102  return tls.connect(options)
103}