Class: Polyphony::ResourcePool

Inherits:
Object
  • Object
show all
Defined in:
lib/polyphony/core/resource_pool.rb

Overview

Implements a limited resource pool

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(limit: 4, &block) ⇒ ResourcePool

Initializes a new resource pool. The given block is used for creating a resource:

ResourcePool.new { Sequel.connect(DB_URL) }

Parameters:

  • limit (Integer) (defaults to: 4)

    maximum open resources



14
15
16
17
18
19
20
# File 'lib/polyphony/core/resource_pool.rb', line 14

def initialize(limit: 4, &block)
  @allocator = block
  @limit = limit
  @size = 0
  @stock = Polyphony::Queue.new
  @acquired_resources = {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args, &block) ⇒ any

Acquires a resource, proxies the method calls to the resource, then releases it. Methods can also be called with blocks, as in the following example:

db_pool.query(sql) { |result| process_result_rows(result) }

Parameters:

  • sym (Symbol)

    method name

  • args (Array<any>)

    method arguments

Returns:

  • (any)

    result of method call



60
61
62
# File 'lib/polyphony/core/resource_pool.rb', line 60

def method_missing(sym, *args, &block)
  acquire { |r| r.send(sym, *args, &block) }
end

Instance Attribute Details

#limitObject (readonly)

Returns the value of attribute limit.



6
7
8
# File 'lib/polyphony/core/resource_pool.rb', line 6

def limit
  @limit
end

#sizeObject (readonly)

Returns the value of attribute size.



6
7
8
# File 'lib/polyphony/core/resource_pool.rb', line 6

def size
  @size
end

Instance Method Details

#acquire(&block) ⇒ any

Acquires a resource, passing it to the given block. If no resource is available, blocks until a resource becomes available. After the block has run, the resource is released back to the pool. The resource is passed to the block as its only argument.

This method is re-entrant: if called from the same fiber, it will immediately return the resource currently acquired by the fiber.

rows = db_pool.acquire do |db| db.query(sql).to_a end

Returns:

  • (any)

    return value of block



42
43
44
45
46
47
# File 'lib/polyphony/core/resource_pool.rb', line 42

def acquire(&block)
  fiber = Fiber.current
  return yield @acquired_resources[fiber] if @acquired_resources[fiber]

  acquire_from_stock(fiber, &block)
end

#availableInteger

Returns number of currently available resources.

Returns:

  • (Integer)

    size of resource stock



25
26
27
# File 'lib/polyphony/core/resource_pool.rb', line 25

def available
  @stock.size
end

#discard!Polyphony::ResourcePool

Discards the currently-acquired resource instead of returning it to the pool when done.

Returns:



73
74
75
76
# File 'lib/polyphony/core/resource_pool.rb', line 73

def discard!
  @size -= 1 if @acquired_resources.delete(Fiber.current)
  self
end

#fill!Polyphony::ResourcePool

Fills the pool to capacity.

Returns:



81
82
83
84
# File 'lib/polyphony/core/resource_pool.rb', line 81

def fill!
  add_to_stock while @size < @limit
  self
end