class Puppet::HTTP::Pool

A pool for persistent `Net::HTTP` connections. Connections are stored in the pool indexed by their {Site}. Connections are borrowed from the pool, yielded to the caller, and released back into the pool. If a connection is expired, it will be closed either when a connection to that site is requested, or when the pool is closed. The pool can store multiple connections to the same site, and will be reused in MRU order.

@api private

Attributes

factory[R]
keepalive_timeout[R]

Public Class Methods

new(keepalive_timeout) click to toggle source
   # File lib/puppet/http/pool.rb
14 def initialize(keepalive_timeout)
15   @pool = {}
16   @factory = Puppet::HTTP::Factory.new
17   @keepalive_timeout = keepalive_timeout
18 end

Public Instance Methods

active_entries(site) click to toggle source

Returns an Array of entries whose connections are not expired.

@api private

    # File lib/puppet/http/pool.rb
143 def active_entries(site)
144   now = Time.now
145 
146   entries = @pool[site] || []
147   entries.select do |entry|
148     if entry.expired?(now)
149       close_connection(site, entry.connection)
150       false
151     else
152       true
153     end
154   end
155 end
borrow(site, verifier) click to toggle source

Borrow and take ownership of a persistent connection. If a new connection is created, it will be started prior to being returned.

@api private

    # File lib/puppet/http/pool.rb
 93 def borrow(site, verifier)
 94   @pool[site] = active_entries(site)
 95   index = @pool[site].index do |entry|
 96     (verifier.nil? && entry.verifier.nil?) ||
 97       (!verifier.nil? && verifier.reusable?(entry.verifier))
 98   end
 99   entry = index ? @pool[site].delete_at(index) : nil
100   if entry
101     @pool.delete(site) if @pool[site].empty?
102 
103     Puppet.debug("Using cached connection for #{site}")
104     entry.connection
105   else
106     http = @factory.create_connection(site)
107 
108     start(site, verifier, http)
109     setsockopts(http.instance_variable_get(:@socket))
110     http
111   end
112 end
close() click to toggle source
   # File lib/puppet/http/pool.rb
42 def close
43   @pool.each_pair do |site, entries|
44     entries.each do |entry|
45       close_connection(site, entry.connection)
46     end
47   end
48   @pool.clear
49 end
close_connection(site, http) click to toggle source

Safely close a persistent connection. Don't try to close a connection that's already closed.

@api private

   # File lib/puppet/http/pool.rb
79 def close_connection(site, http)
80   return false unless http.started?
81   Puppet.debug("Closing connection for #{site}")
82   http.finish
83   true
84 rescue => detail
85   Puppet.log_exception(detail, _("Failed to close connection for %{site}: %{detail}") % { site: site, detail: detail })
86   nil
87 end
pool() click to toggle source

@api private

   # File lib/puppet/http/pool.rb
52 def pool
53   @pool
54 end
release(site, verifier, http) click to toggle source

Release a connection back into the pool.

@api private

    # File lib/puppet/http/pool.rb
127 def release(site, verifier, http)
128   expiration = Time.now + @keepalive_timeout
129   entry = Puppet::HTTP::PoolEntry.new(http, verifier, expiration)
130   Puppet.debug("Caching connection for #{site}")
131 
132   entries = @pool[site]
133   if entries
134     entries.unshift(entry)
135   else
136     @pool[site] = [entry]
137   end
138 end
setsockopts(netio) click to toggle source

Set useful socket option(s) which lack from default settings in Net:HTTP

@api private

    # File lib/puppet/http/pool.rb
117 def setsockopts(netio)
118   return unless netio
119 
120   socket = netio.io
121   socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
122 end
start(site, verifier, http) click to toggle source

Start a persistent connection

@api private

   # File lib/puppet/http/pool.rb
59 def start(site, verifier, http)
60   Puppet.debug("Starting connection for #{site}")
61   if site.use_ssl?
62     verifier.setup_connection(http)
63     begin
64       http.start
65       print_ssl_info(http) if Puppet::Util::Log.sendlevel?(:debug)
66     rescue OpenSSL::SSL::SSLError => error
67       verifier.handle_connection_error(http, error)
68     end
69   else
70     http.start
71   end
72 end
with_connection(site, verifier) { |http| ... } click to toggle source
   # File lib/puppet/http/pool.rb
20 def with_connection(site, verifier, &block)
21   reuse = true
22 
23   http = borrow(site, verifier)
24   begin
25     if http.use_ssl? && http.verify_mode != OpenSSL::SSL::VERIFY_PEER
26       reuse = false
27     end
28 
29     yield http
30   rescue => detail
31     reuse = false
32     raise detail
33   ensure
34     if reuse && http.started?
35       release(site, verifier, http)
36     else
37       close_connection(site, http)
38     end
39   end
40 end

Private Instance Methods

print_ssl_info(http) click to toggle source