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
13 def initialize(keepalive_timeout)
14   @pool = {}
15   @factory = Puppet::HTTP::Factory.new
16   @keepalive_timeout = keepalive_timeout
17 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
142 def active_entries(site)
143   now = Time.now
144 
145   entries = @pool[site] || []
146   entries.select do |entry|
147     if entry.expired?(now)
148       close_connection(site, entry.connection)
149       false
150     else
151       true
152     end
153   end
154 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
 92 def borrow(site, verifier)
 93   @pool[site] = active_entries(site)
 94   index = @pool[site].index do |entry|
 95     (verifier.nil? && entry.verifier.nil?) ||
 96       (!verifier.nil? && verifier.reusable?(entry.verifier))
 97   end
 98   entry = index ? @pool[site].delete_at(index) : nil
 99   if entry
100     @pool.delete(site) if @pool[site].empty?
101 
102     Puppet.debug("Using cached connection for #{site}")
103     entry.connection
104   else
105     http = @factory.create_connection(site)
106 
107     start(site, verifier, http)
108     setsockopts(http.instance_variable_get(:@socket))
109     http
110   end
111 end
close() click to toggle source
   # File lib/puppet/http/pool.rb
41 def close
42   @pool.each_pair do |site, entries|
43     entries.each do |entry|
44       close_connection(site, entry.connection)
45     end
46   end
47   @pool.clear
48 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
78 def close_connection(site, http)
79   return false unless http.started?
80   Puppet.debug("Closing connection for #{site}")
81   http.finish
82   true
83 rescue => detail
84   Puppet.log_exception(detail, _("Failed to close connection for %{site}: %{detail}") % { site: site, detail: detail })
85   nil
86 end
pool() click to toggle source

@api private

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

Release a connection back into the pool.

@api private

    # File lib/puppet/http/pool.rb
126 def release(site, verifier, http)
127   expiration = Time.now + @keepalive_timeout
128   entry = Puppet::HTTP::PoolEntry.new(http, verifier, expiration)
129   Puppet.debug("Caching connection for #{site}")
130 
131   entries = @pool[site]
132   if entries
133     entries.unshift(entry)
134   else
135     @pool[site] = [entry]
136   end
137 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
116 def setsockopts(netio)
117   return unless netio
118 
119   socket = netio.io
120   socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
121 end
start(site, verifier, http) click to toggle source

Start a persistent connection

@api private

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

Private Instance Methods

print_ssl_info(http) click to toggle source