Class: FTW::Pool

Inherits:
Object
  • Object
show all
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

Constructor Details

#initializePool

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