Class: A2A::Client::ConnectionPool
- Inherits:
-
Object
- Object
- A2A::Client::ConnectionPool
- Includes:
- MonitorMixin
- Defined in:
- lib/a2a/client/connection_pool.rb
Overview
Connection pool manager for HTTP clients
Manages a pool of HTTP connections to improve performance by reusing connections and avoiding the overhead of establishing new connections for each request.
Constant Summary collapse
- DEFAULT_POOL_SIZE =
Default pool configuration
5- DEFAULT_TIMEOUT =
5- DEFAULT_IDLE_TIMEOUT =
30
Instance Attribute Summary collapse
-
#checked_out ⇒ Object
readonly
Returns the value of attribute checked_out.
-
#created ⇒ Object
readonly
Returns the value of attribute created.
-
#idle_timeout ⇒ Object
readonly
Returns the value of attribute idle_timeout.
-
#size ⇒ Object
readonly
Returns the value of attribute size.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
Instance Method Summary collapse
-
#checkin(connection) ⇒ Object
Check in a connection to the pool.
-
#checkout ⇒ Object
Check out a connection from the pool.
-
#cleanup_idle_connections ⇒ Object
private
Clean up idle connections.
-
#close_all ⇒ Object
Close all connections in the pool.
-
#close_connection(connection) ⇒ Object
private
Close a connection.
-
#create_connection ⇒ Object
private
Create a new connection.
-
#flush_idle! ⇒ Object
Flush idle connections from the pool.
-
#initialize(size: DEFAULT_POOL_SIZE, timeout: DEFAULT_TIMEOUT, idle_timeout: DEFAULT_IDLE_TIMEOUT) { ... } ⇒ ConnectionPool
constructor
Initialize a new connection pool.
-
#should_cleanup? ⇒ Boolean
private
Check if we should run cleanup.
-
#stats ⇒ Hash
Get pool statistics.
-
#valid_connection?(connection) ⇒ Boolean
private
Check if a connection is valid.
-
#with_connection {|connection| ... } ⇒ Object
Execute a block with a connection from the pool.
Constructor Details
#initialize(size: DEFAULT_POOL_SIZE, timeout: DEFAULT_TIMEOUT, idle_timeout: DEFAULT_IDLE_TIMEOUT) { ... } ⇒ ConnectionPool
Initialize a new connection pool
31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/a2a/client/connection_pool.rb', line 31 def initialize(size: DEFAULT_POOL_SIZE, timeout: DEFAULT_TIMEOUT, idle_timeout: DEFAULT_IDLE_TIMEOUT, &block) super() @size = size @timeout = timeout @idle_timeout = idle_timeout @connection_factory = block @pool = [] @checked_out = [] @created = 0 @last_cleanup = Time.now end |
Instance Attribute Details
#checked_out ⇒ Object (readonly)
Returns the value of attribute checked_out.
22 23 24 |
# File 'lib/a2a/client/connection_pool.rb', line 22 def checked_out @checked_out end |
#created ⇒ Object (readonly)
Returns the value of attribute created.
22 23 24 |
# File 'lib/a2a/client/connection_pool.rb', line 22 def created @created end |
#idle_timeout ⇒ Object (readonly)
Returns the value of attribute idle_timeout.
22 23 24 |
# File 'lib/a2a/client/connection_pool.rb', line 22 def idle_timeout @idle_timeout end |
#size ⇒ Object (readonly)
Returns the value of attribute size.
22 23 24 |
# File 'lib/a2a/client/connection_pool.rb', line 22 def size @size end |
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
22 23 24 |
# File 'lib/a2a/client/connection_pool.rb', line 22 def timeout @timeout end |
Instance Method Details
#checkin(connection) ⇒ Object
Check in a connection to the pool
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/a2a/client/connection_pool.rb', line 83 def checkin(connection) synchronize do @checked_out.delete(connection) # Add connection back to pool if it's still valid if valid_connection?(connection) connection.instance_variable_set(:@last_used, Time.now) @pool.push(connection) else # Connection is invalid, create a new one to replace it @created -= 1 end end end |
#checkout ⇒ Object
Check out a connection from the pool
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/a2a/client/connection_pool.rb', line 49 def checkout synchronize do # Try to get an existing connection connection = @pool.pop # Create a new connection if pool is empty and we haven't reached the limit connection = create_connection if connection.nil? && @created < @size # Wait for a connection to become available if connection.nil? deadline = Time.now + @timeout while connection.nil? && Time.now < deadline ns_wait(0.1) # Wait 100ms connection = @pool.pop end raise TimeoutError, "Could not checkout connection within #{@timeout}s" if connection.nil? end # Mark connection as checked out @checked_out << connection # Cleanup idle connections periodically cleanup_idle_connections if should_cleanup? connection end end |
#cleanup_idle_connections ⇒ Object (private)
Clean up idle connections
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/a2a/client/connection_pool.rb', line 211 def cleanup_idle_connections @last_cleanup = Time.now cutoff_time = Time.now - @idle_timeout @pool.reject! do |connection| last_used = connection.instance_variable_get(:@last_used) if last_used && last_used < cutoff_time close_connection(connection) @created -= 1 true else false end end end |
#close_all ⇒ Object
Close all connections in the pool
132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/a2a/client/connection_pool.rb', line 132 def close_all synchronize do (@pool + @checked_out).each do |connection| close_connection(connection) end @pool.clear @checked_out.clear @created = 0 end end |
#close_connection(connection) ⇒ Object (private)
Close a connection
194 195 196 197 198 |
# File 'lib/a2a/client/connection_pool.rb', line 194 def close_connection(connection) connection.close if connection.respond_to?(:close) rescue StandardError # Ignore errors when closing connections end |
#create_connection ⇒ Object (private)
Create a new connection
159 160 161 162 163 164 165 166 167 168 |
# File 'lib/a2a/client/connection_pool.rb', line 159 def create_connection return nil unless @connection_factory connection = @connection_factory.call connection.instance_variable_set(:@created_at, Time.now) connection.instance_variable_set(:@last_used, Time.now) @created += 1 connection end |
#flush_idle! ⇒ Object
Flush idle connections from the pool
147 148 149 150 151 |
# File 'lib/a2a/client/connection_pool.rb', line 147 def flush_idle! synchronize do cleanup_idle_connections end end |
#should_cleanup? ⇒ Boolean (private)
Check if we should run cleanup
204 205 206 |
# File 'lib/a2a/client/connection_pool.rb', line 204 def should_cleanup? Time.now - @last_cleanup > 60 # Cleanup every minute end |
#stats ⇒ Hash
Get pool statistics
116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/a2a/client/connection_pool.rb', line 116 def stats synchronize do { size: @size, created: @created, available: @pool.size, checked_out: @checked_out.size, idle_timeout: @idle_timeout, timeout: @timeout } end end |
#valid_connection?(connection) ⇒ Boolean (private)
Check if a connection is valid
175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/a2a/client/connection_pool.rb', line 175 def valid_connection?(connection) return false unless connection # Check if connection responds to basic methods return false unless connection.respond_to?(:get) || connection.respond_to?(:request) # Check if connection is not too old created_at = connection.instance_variable_get(:@created_at) return false if created_at && (Time.now - created_at) > (@idle_timeout * 10) true rescue StandardError false end |
#with_connection {|connection| ... } ⇒ Object
Execute a block with a connection from the pool
103 104 105 106 107 108 109 110 |
# File 'lib/a2a/client/connection_pool.rb', line 103 def with_connection connection = checkout begin yield connection ensure checkin(connection) end end |