Class: FTW::Pool
- Inherits:
-
Object
- Object
- FTW::Pool
- Defined in:
- lib/ftw/pool.rb
Overview
A simple thread-safe resource pool.
Resources in this pool must respond to ‘available?’. For best results, your resources should just ‘include FTW::Poolable’
The primary use case was as a way to pool FTW::Connection instances.
Instance Method Summary collapse
-
#add(identifier, object) ⇒ Object
Add an object to the pool with a given identifier.
-
#each(&block) ⇒ Object
Iterate over all pool members.
-
#fetch(identifier, &default_block) ⇒ Object
Fetch a resource from this pool.
-
#initialize ⇒ Pool
constructor
A new instance of Pool.
Constructor Details
#initialize ⇒ Pool
Returns a new instance of Pool.
11 12 13 14 15 |
# File 'lib/ftw/pool.rb', line 11 def initialize # Pool is a hash of arrays. @pool = Hash.new { |h,k| h[k] = Array.new } @lock = Mutex.new end |
Instance Method Details
#add(identifier, object) ⇒ Object
Add an object to the pool with a given identifier. For example:
pool.add("www.google.com:80", connection1)
pool.add("www.google.com:80", connection2)
pool.add("github.com:443", connection3)
22 23 24 25 26 27 |
# File 'lib/ftw/pool.rb', line 22 def add(identifier, object) @lock.synchronize do @pool[identifier] << object end return object end |
#each(&block) ⇒ Object
Iterate over all pool members.
This holds the pool lock during this method, so you should not call ‘fetch’ or ‘add’.
61 62 63 64 65 66 67 |
# File 'lib/ftw/pool.rb', line 61 def each(&block) @lock.synchronize do @pool.each do |identifier, object| block.call(identifier, object) end end end |
#fetch(identifier, &default_block) ⇒ Object
Fetch a resource from this pool. If no available resources are found, the ‘default_block’ is invoked and expected to return a new resource to add to the pool that satisfies the fetch..
Example:
pool.fetch("github.com:443") do
conn = FTW::Connection.new("github.com:443")
conn.secure
conn
end
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/ftw/pool.rb', line 41 def fetch(identifier, &default_block) @lock.synchronize do @pool[identifier].delete_if { |o| o.available? && !o.connected? } object = @pool[identifier].find { |o| o.available? } return object if !object.nil? end # Otherwise put the return value of default_block in the # pool and return it, but don't put nil values in the pool. obj = default_block.call if obj.nil? return nil else return add(identifier, obj) end end |