Class: Pod4::ConnectionPool
- Inherits:
-
Connection
- Object
- Connection
- Pod4::ConnectionPool
- Defined in:
- lib/pod4/connection_pool.rb
Defined Under Namespace
Constant Summary collapse
- DEFAULT_MAX_CLIENTS =
10
Instance Attribute Summary collapse
-
#max_clients ⇒ Object
readonly
of Pool.
-
#max_wait ⇒ Object
readonly
of Pool.
Attributes inherited from Connection
#data_layer_options, #interface_class
Instance Method Summary collapse
-
#_pool ⇒ Object
Dump the internal pool (for test purposes only).
-
#client(interface) ⇒ Object
Return a client for the interface to use.
-
#close(interface) ⇒ Object
De-assign the client for the current thread from that thread.
-
#drop(interface) ⇒ Object
Remove the client from the pool but don’t try to close it.
-
#initialize(args) ⇒ ConnectionPool
constructor
As Connection, but with some options you can set.
Constructor Details
#initialize(args) ⇒ ConnectionPool
As Connection, but with some options you can set.
-
max_clients – if this many clients are assigned to threads, wait until one is freed.
pass nil for no maximum. Tries to default to something sensible.
-
max_wait – throw a Pod4::PoolTimeout if you wait more than this time in seconds.
Pass nil to wait forever. Default is nil, because you would need to handle that timeout.
Note that the :interface parameter is optional here. You probably want one pool for all your models and interfaces, so you should leave it out.
80 81 82 83 84 85 86 |
# File 'lib/pod4/connection_pool.rb', line 80 def initialize(args) super(args) @max_clients = args[:max_clients] || DEFAULT_MAX_CLIENTS @max_wait = args[:max_wait] @pool = Pool.new end |
Instance Attribute Details
#max_clients ⇒ Object (readonly)
of Pool
64 65 66 |
# File 'lib/pod4/connection_pool.rb', line 64 def max_clients @max_clients end |
#max_wait ⇒ Object (readonly)
of Pool
64 65 66 |
# File 'lib/pod4/connection_pool.rb', line 64 def max_wait @max_wait end |
Instance Method Details
#_pool ⇒ Object
Dump the internal pool (for test purposes only)
171 172 173 |
# File 'lib/pod4/connection_pool.rb', line 171 def _pool @pool._dump end |
#client(interface) ⇒ Object
Return a client for the interface to use.
Return the client we gave this thread before. Failing that, assign a free one from the pool. Failing that, ask the interface to give us a new client. Failing that, if we’ve set a timeout, wait for a client to be freed; if we have not, release
the oldest client and use that.
Note: ‘interface’ is the instance of the interface class. It passes itself in case we want to call it back to get a new client or to close a client; but clients are assigned to a thread, not an interface. Every interface in a given thread gets the same pool item, the same client object.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/pod4/connection_pool.rb', line 102 def client(interface) time = Time.now cl = nil Pod4.logger.debug(__FILE__){ "Pool size: #{@pool.size} Thread: #{Thread.current.object_id}" } # NB: We are constrained to use loop in order for our test to work loop do if (pi = @pool.get_current) Pod4.logger.debug(__FILE__){ "get current: #{pi.inspect}" } cl = pi.client break end if (pi = @pool.get_free) Pod4.logger.debug(__FILE__){ "get free: #{pi.inspect}" } cl = pi.client break end if @max_clients && @pool.size >= @max_clients if @max_wait raise Pod4::PoolTimeout if @max_wait && (Time.now - time > @max_wait) Pod4.logger.warn(__FILE__){ "waiting for a free client..." } sleep 1 next else Pod4.logger.debug(__FILE__){ "releasing oldest client" } oldest = @pool.get_oldest interface.close_connection oldest.client @pool.release(oldest.thread_id) next end end Pod4.logger.debug(__FILE__){ "new connection" } cl = interface.new_connection() @pool << cl break end # of loop Pod4.logger.debug(__FILE__){ "Got client: #{cl.inspect}" } cl end |
#close(interface) ⇒ Object
De-assign the client for the current thread from that thread.
Note: ‘interface’ is the instance of the interface class. This is so we can call it and get it to close the client; we don’t know how to do that.
153 154 155 156 157 |
# File 'lib/pod4/connection_pool.rb', line 153 def close(interface) current = @pool.get_current interface.close_connection current.client @pool.release current.thread_id end |
#drop(interface) ⇒ Object
Remove the client from the pool but don’t try to close it. we provide this for if the Interface finds that a connection is no longer open; TdsInterface uses it.
164 165 166 |
# File 'lib/pod4/connection_pool.rb', line 164 def drop(interface) @pool.release end |