Methods
Public Class
Public Instance
Constants
POOL_TIMEOUT | = | 5 |
Public Class methods
new(options)
Sets up the connection pool with the given options
, which can be the following:
:max_connections |
the maximum number of connections held in the pool. |
:max_connections_per_origin |
the maximum number of connections held in the pool pointing to a given origin. |
:pool_timeout |
the number of seconds to wait for a connection to a given origin (before raising |
[show source]
# File lib/httpx/pool.rb 20 def initialize(options) 21 @max_connections = options.fetch(:max_connections, Float::INFINITY) 22 @max_connections_per_origin = options.fetch(:max_connections_per_origin, Float::INFINITY) 23 @pool_timeout = options.fetch(:pool_timeout, POOL_TIMEOUT) 24 @resolvers = Hash.new { |hs, resolver_type| hs[resolver_type] = [] } 25 @resolver_mtx = Thread::Mutex.new 26 @connections = [] 27 @connection_mtx = Thread::Mutex.new 28 @connections_counter = 0 29 @max_connections_cond = ConditionVariable.new 30 @origin_counters = Hash.new(0) 31 @origin_conds = Hash.new { |hs, orig| hs[orig] = ConditionVariable.new } 32 end
Public Instance methods
checkin_connection(connection)
[show source]
# File lib/httpx/pool.rb 85 def checkin_connection(connection) 86 return if connection.options.io 87 88 @connection_mtx.synchronize do 89 @connections << connection 90 91 @max_connections_cond.signal 92 @origin_conds[connection.origin.to_s].signal 93 end 94 end
checkin_resolver(resolver)
[show source]
# File lib/httpx/pool.rb 128 def checkin_resolver(resolver) 129 @resolver_mtx.synchronize do 130 resolvers = @resolvers[resolver.class] 131 132 resolver = resolver.multi 133 134 resolvers << resolver unless resolvers.include?(resolver) 135 end 136 end
checkout_connection(uri, options)
opens a connection to the IP reachable through uri
. Many hostnames are reachable through the same IP, so we try to maximize pipelining by opening as few connections as possible.
[show source]
# File lib/httpx/pool.rb 45 def checkout_connection(uri, options) 46 return checkout_new_connection(uri, options) if options.io 47 48 @connection_mtx.synchronize do 49 acquire_connection(uri, options) || begin 50 if @connections_counter == @max_connections 51 # this takes precedence over per-origin 52 @max_connections_cond.wait(@connection_mtx, @pool_timeout) 53 54 acquire_connection(uri, options) || begin 55 if @connections_counter == @max_connections 56 # if no matching usable connection was found, the pool will make room and drop a closed connection. if none is found, 57 # this means that all of them are persistent or being used, so raise a timeout error. 58 conn = @connections.find { |c| c.state == :closed } 59 60 raise PoolTimeoutError.new(@pool_timeout, 61 "Timed out after #{@pool_timeout} seconds while waiting for a connection") unless conn 62 63 drop_connection(conn) 64 end 65 end 66 end 67 68 if @origin_counters[uri.origin] == @max_connections_per_origin 69 70 @origin_conds[uri.origin].wait(@connection_mtx, @pool_timeout) 71 72 return acquire_connection(uri, options) || 73 raise(PoolTimeoutError.new(@pool_timeout, 74 "Timed out after #{@pool_timeout} seconds while waiting for a connection to #{uri.origin}")) 75 end 76 77 @connections_counter += 1 78 @origin_counters[uri.origin] += 1 79 80 checkout_new_connection(uri, options) 81 end 82 end 83 end
checkout_mergeable_connection(connection)
[show source]
# File lib/httpx/pool.rb 96 def checkout_mergeable_connection(connection) 97 return if connection.options.io 98 99 @connection_mtx.synchronize do 100 idx = @connections.find_index do |ch| 101 ch != connection && ch.mergeable?(connection) 102 end 103 if idx 104 @connections_counter -= 1 105 @connections.delete_at(idx) 106 end 107 end 108 end
checkout_resolver(options)
[show source]
# File lib/httpx/pool.rb 114 def checkout_resolver(options) 115 resolver_type = options.resolver_class 116 resolver_type = Resolver.resolver_for(resolver_type) 117 118 @resolver_mtx.synchronize do 119 resolvers = @resolvers[resolver_type] 120 121 idx = resolvers.find_index do |res| 122 res.options == options 123 end 124 resolvers.delete_at(idx) if idx 125 end || checkout_new_resolver(resolver_type, options) 126 end
inspect()
:nocov:
[show source]
# File lib/httpx/pool.rb 139 def inspect 140 "#<#{self.class}:#{object_id} " \ 141 "@max_connections_per_origin=#{@max_connections_per_origin} " \ 142 "@pool_timeout=#{@pool_timeout} " \ 143 "@connections=#{@connections.size}>" 144 end
pop_connection()
connections returned by this function are not expected to return to the connection pool.
[show source]
# File lib/httpx/pool.rb 35 def pop_connection 36 @connection_mtx.synchronize do 37 drop_connection 38 end 39 end
reset_resolvers()
[show source]
# File lib/httpx/pool.rb 110 def reset_resolvers 111 @resolver_mtx.synchronize { @resolvers.clear } 112 end