class Net::HTTP::ConnectionPool

A wrapper around Net::HTTP that provides a manged pool of persistant HTTP connections.

pool = Net::HTTP::ConnectionPool.new
connection = pool.connection_for('domain.com')
connection.request(Net::HTTP::Get.new('/')) do |resp|
  # Connection#request yields Net::HTTPResponse objects
  puts resp.body
end

@private

Attributes

http_wire_trace[R]

@return [Boolean] Returns true when HTTP debug output (wire traces)

will be logged.
http_wire_trace?[R]

@return [Boolean] Returns true when HTTP debug output (wire traces)

will be logged.
idle_timeout[R]

@return [Integer]

log_wire_trace[R]

@return [Boolean] Returns true when HTTP debug output (wire traces)

will be logged.
log_wire_trace?[R]

@return [Boolean] Returns true when HTTP debug output (wire traces)

will be logged.
logger[R]

@return [Logger] Where debug output is sent.

open_timeout[RW]

@return [Integer]

Public Class Methods

new(options = {}) click to toggle source

@param [Hash] options

@option options [Numeric] :http_idle_timeout (60) The number of seconds a

connection is allowed to sit idle before it is closed and removed
from the pool.

@option options [Numeric] :http_open_timeout (15) The number of seconds to

wait when opening a http session before raising a timeout exception.

@option options [Boolean] :http_wire_trace (false) When true, HTTP

debug output will be sent to the +:logger+.

@option options [Logger] :logger (Logger.new($stdout)) Where debug out

is sent (wire traces).
# File lib/net/http/connection_pool.rb, line 47
def initialize options = {}
  @pool_mutex = Mutex.new
  @pool = []
  @open_timeout = options[:http_open_timeout] || 15
  @idle_timeout = options[:http_idle_timeout] || 60
  @http_wire_trace = !!options[:http_wire_trace]
  if logger = options[:logger]
    @logger = logger
  elsif http_wire_trace?
    @logger = Logger.new($stdout)
  end
end

Public Instance Methods

clean!() click to toggle source

Removes stale http sessions from the pool (that have exceeded the idle timeout).

# File lib/net/http/connection_pool.rb, line 152
def clean!
  @pool_mutex.synchronize { _clean }
end
connection_for(host, options = {}) { |connection| ... } click to toggle source

Requests a connection object from the connection pool.

connection = pool.connection_for('domain.com')
connection.request(Net::HTTP::Get.new('/index.html')) {|resp|}
connection.request(Net::HTTP::Get.new('/about.html')) {|resp|}

# same thing in block form
pool.connection_for('domain.com') do |connection|
  connection.request(Net::HTTP::Get.new('/index.html')) {|resp|}
  connection.request(Net::HTTP::Get.new('/about.html')) {|resp|}
end

Because the pool manages HTTP sessions you do not have to worry about closing a connection or returning a connection to the pool.

@param [String] host

@param [Hash] options

@option options [Integer] :port Which port the connection should use.

Defaults to 80, unless +:ssl+ is +true+, then it defaults to 443.

@option options [Boolean] :ssl If the connection should be made over

SSL.  Defaults to +false+, unless +:port+ is 443, then it defaults
to +true+.

@option options [Boolean] :ssl_verify_peer (true) If true, ssl

connections should verify peer certificates.  This should only ever be
set false false for debugging purposes.

@option options [String] :ssl_ca_file Full path to the SSL certificate

authority bundle file that should be used when verifying peer
certificates.  If you do not pass +:ssl_ca_file+ or +:ssl_ca_path+
the the system default will be used if available.

@option options [String] :ssl_ca_path Full path of the directory that

contains the unbundled SSL certificate authority files for verifying
peer certificates.  If you do not pass +:ssl_ca_file+ or +:ssl_ca_path+
the the system default will be used if available.

@option options [URI::HTTP,String] :proxy_uri (nil) A URI string or

URI::HTTP object to use as a proxy.  You should not provide
+:proxy_uri+ with any other proxy options.

  :proxy_uri => 'http://user:pass@host.com:80'

@option options [String] :proxy_address

@option options [String] :proxy_port

@option options [String] :proxy_user

@option options [String] :proxy_password

@yield [connection]

@yieldparam [optional,Connection] connection

@return [Connection]

# File lib/net/http/connection_pool.rb, line 138
def connection_for host, options = {}, &block
  connection = Connection.new(self, host, options)
  yield(connection) if block_given?
  connection
end
empty!() click to toggle source

Closes and removes removes all sessions from the pool. If empty! is called while there are outstanding requests they may get checked back into the pool, leaving the pool in a non-empty state.

# File lib/net/http/connection_pool.rb, line 159
def empty!
  @pool_mutex.synchronize do
    @pool.each(&:finish)
    @pool = []
  end
end
request(connection, *args, &block) click to toggle source

Makes a single HTTP request. See {Connection#request} for more information on making an HTTP request. @return [nil] @private

# File lib/net/http/connection_pool.rb, line 170
def request connection, *args, &block
  session_for(connection) do |session|
    session.read_timeout = connection.read_timeout
    session.request(*args, &block)
  end
end
size() click to toggle source

Returns the number of sessions currently in the pool, not counting those currently in use.

# File lib/net/http/connection_pool.rb, line 146
def size
  @pool_mutex.synchronize { @pool.size }
end

Protected Instance Methods

_clean() click to toggle source
# File lib/net/http/connection_pool.rb, line 213
def _clean
  now = Time.now
  @pool.delete_if do |idle_session|
    if
      idle_session.last_used_at.nil? or
      now - idle_session.last_used_at > idle_timeout
    then
      idle_session.finish
      true
    end
  end
end
_create_session(connection) click to toggle source
# File lib/net/http/connection_pool.rb, line 207
def _create_session connection
  Session.start(connection,
    :open_timeout => open_timeout,
    :debug_logger => log_wire_trace? ? logger : nil)
end
session_for(connection) { |session| ... } click to toggle source

Yields an open http session for the given connection.

# File lib/net/http/connection_pool.rb, line 180
def session_for connection, &block

  session = nil

  # search the pool for an idle session that can be used
  @pool_mutex.synchronize do
    _clean # removes stale sessions
    session = @pool.find{|idle_session| idle_session.key == connection.key }
    @pool.delete(session) if session
  end

  begin
    # opens a new HTTP session if no suitable idle session was found
    session = _create_session(connection) unless session
    yield(session)
  rescue Exception => error
    session.finish if session
    raise error
  else
    # only check the session back into the pool if no errors were raised
    @pool_mutex.synchronize { @pool << session }
  end

  nil

end