Class: HttpConnectionPool::Pool
- Inherits:
-
Object
- Object
- HttpConnectionPool::Pool
- Defined in:
- lib/http_connection_pool/pool.rb
Overview
Manages a pool of persistent HTTP::Session connections for a single URL origin. On http v6, HTTP.persistent returns an HTTP::Session, and http’s own README notes that a persistent session is not thread-safe on its own — it points to the ‘connection_pool` gem for thread-safe persistent use. That is exactly the pattern this class follows: each caller checks out its own Session for the duration of a request.
Backed by the ‘connection_pool` gem (>= 2.5.5), which is both thread- and Fiber.scheduler-aware: when running under a fiber scheduler, blocking checkouts yield to the scheduler instead of parking the OS thread.
Pool instances are never created directly — obtain them through Registry.
Constant Summary collapse
- TimeoutError =
Backward-compatible aliases — the canonical classes live in errors.rb under HttpConnectionPool. Existing ‘rescue Pool::TimeoutError` keeps working.
HttpConnectionPool::TimeoutError
- ClosedError =
HttpConnectionPool::ClosedError
- DEFAULT_SIZE =
5- DEFAULT_TIMEOUT =
seconds to wait for a connection to become available
5.0
Instance Attribute Summary collapse
-
#origin ⇒ Object
readonly
Returns the value of attribute origin.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
Instance Method Summary collapse
-
#close ⇒ Object
Immediately close every connection and mark the pool as closed.
- #closed? ⇒ Boolean
-
#initialize(origin:, size: DEFAULT_SIZE, timeout: DEFAULT_TIMEOUT, **options) ⇒ Pool
constructor
A new instance of Pool.
-
#inspect ⇒ Object
(also: #to_s)
Redacted inspect.
-
#pretty_print(pp) ⇒ Object
Belt-and-suspenders for pretty-printers (pp / awesome_print), which call #pretty_print rather than #inspect and would otherwise reach @options.
- #stats ⇒ Object
-
#with {|conn| ... } ⇒ Object
Yields a live HTTP::Session scoped to @origin, returning it to the pool when done.
Constructor Details
#initialize(origin:, size: DEFAULT_SIZE, timeout: DEFAULT_TIMEOUT, **options) ⇒ Pool
Returns a new instance of Pool.
37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/http_connection_pool/pool.rb', line 37 def initialize(origin:, size: DEFAULT_SIZE, timeout: DEFAULT_TIMEOUT, **) @origin = origin @size = Integer(size) @timeout = Float(timeout) @options = deep_freeze() raise ArgumentError, 'size must be >= 1' unless @size >= 1 raise ArgumentError, 'timeout must be > 0' unless @timeout.positive? @closed = Concurrent::AtomicBoolean.new(false) @pool = ::ConnectionPool.new(size: @size, timeout: @timeout) { build_connection } end |
Instance Attribute Details
#origin ⇒ Object (readonly)
Returns the value of attribute origin.
50 51 52 |
# File 'lib/http_connection_pool/pool.rb', line 50 def origin @origin end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
50 51 52 |
# File 'lib/http_connection_pool/pool.rb', line 50 def size @size end |
Instance Method Details
#close ⇒ Object
Immediately close every connection and mark the pool as closed. Any subsequent call to #with will raise ClosedError.
73 74 75 76 77 78 79 80 81 82 |
# File 'lib/http_connection_pool/pool.rb', line 73 def close return unless @closed.make_true @pool.shutdown do |conn| conn&.close rescue StandardError # Closing a stale connection should not mask the shutdown. nil end end |
#closed? ⇒ Boolean
84 85 86 |
# File 'lib/http_connection_pool/pool.rb', line 84 def closed? @closed.true? end |
#inspect ⇒ Object Also known as: to_s
Redacted inspect. The default Ruby #inspect would dump @options verbatim, exposing any Authorization header / auth token / SSL material in logs, backtraces, and error-reporting payloads. We list only the option keys (never their values) plus the non-sensitive pool state.
103 104 105 106 107 108 |
# File 'lib/http_connection_pool/pool.rb', line 103 def inspect keys = @options.keys option_keys = keys.empty? ? 'none' : keys.join(', ') "#<#{self.class.name} origin=#{@origin.inspect} size=#{@size} " \ "timeout=#{@timeout} closed=#{closed?} options=[#{option_keys}]>" end |
#pretty_print(pp) ⇒ Object
Belt-and-suspenders for pretty-printers (pp / awesome_print), which call #pretty_print rather than #inspect and would otherwise reach @options.
113 114 115 |
# File 'lib/http_connection_pool/pool.rb', line 113 def pretty_print(pp) pp.text(inspect) end |
#stats ⇒ Object
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/http_connection_pool/pool.rb', line 88 def stats available = @pool.available { origin: @origin, size: @size, checked_out: @size - available, idle: available, closed: closed? } end |
#with {|conn| ... } ⇒ Object
Yields a live HTTP::Session scoped to @origin, returning it to the pool when done.
58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/http_connection_pool/pool.rb', line 58 def with(&) raise ClosedError, "pool for #{@origin} is closed" if @closed.true? @pool.with(&) rescue ::ConnectionPool::TimeoutError => e raise TimeoutError, "no connection available for #{@origin} within #{@timeout}s (#{e.})" rescue ::ConnectionPool::PoolShuttingDownError # Another thread closed the pool between our @closed check and checkout. # Surface it as our own ClosedError rather than leaking the backing # library's exception type. raise ClosedError, "pool for #{@origin} is closed" end |