Class: Zoidberg::Pool

Inherits:
Object
  • Object
show all
Includes:
SoftShell
Defined in:
lib/zoidberg/pool.rb

Overview

Populate a collection of instances and proxy requests to free instances within the pool

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SoftShell

#_zoidberg_thread, #async, #defer, included, #sleep

Constructor Details

#initialize(*args, &block) ⇒ self

Create a new pool instance. Provide class + instance initialization arguments when creating the pool. These will be used to build all instances within the pool.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/zoidberg/pool.rb', line 20

def initialize(*args, &block)
  _validate_worker_class!(args.first)
  @_signal = Signal.new
  @_worker_count = 1
  @_workers = []
  @builder = lambda do
    inst = args.first.new(
      *args.slice(1, args.size),
      &block
    )
    inst._zoidberg_signal = _signal
    inst
  end
  _zoidberg_balance
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args, &block) ⇒ Object

Used to proxy request to worker



79
80
81
82
83
# File 'lib/zoidberg/pool.rb', line 79

def method_missing(*args, &block)
  worker = _zoidberg_free_worker
  current_self._release_lock!
  worker.send(*args, &block)
end

Instance Attribute Details

#_signalSignal (readonly)

Returns common signal for state updates.

Returns:

  • (Signal)

    common signal for state updates



13
14
15
# File 'lib/zoidberg/pool.rb', line 13

def _signal
  @_signal
end

#_workersArray<Object> (readonly)

Returns workers within pool.

Returns:

  • (Array<Object>)

    workers within pool



11
12
13
# File 'lib/zoidberg/pool.rb', line 11

def _workers
  @_workers
end

Instance Method Details

#_validate_worker_class!(klass) ⇒ Object

Validate worker class is properly supervised

Raises:

  • (TypeError)


39
40
41
42
43
# File 'lib/zoidberg/pool.rb', line 39

def _validate_worker_class!(klass)
  unless(klass.ancestors.include?(Zoidberg::Supervise))
    raise TypeError.new "Worker class `#{klass}` must include the `Zoidberg::Supervise` module!"
  end
end

#_worker_count(num = nil) ⇒ Integer

Set or get the number of workers within the pool

Parameters:

  • num (Integer) (defaults to: nil)

Returns:

  • (Integer)


49
50
51
52
53
54
55
# File 'lib/zoidberg/pool.rb', line 49

def _worker_count(num=nil)
  if(num)
    @_worker_count = num.to_i
    _zoidberg_balance
  end
  @_worker_count
end

#_zoidberg_balanceTrueClass

Balance the pool to ensure the correct number of workers are available

Returns:

  • (TrueClass)


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/zoidberg/pool.rb', line 61

def _zoidberg_balance
  unless(_workers.size == _worker_count)
    if(_workers.size < _worker_count)
      (_worker_count - _workers.size).times do
        _workers << @builder.call
      end
    else
      (_workers.size - _worker_count).times do
        worker = _zoidberg_free_worker
        worker._zoidberg_destroy!
        _workers.delete(worker)
      end
    end
  end
  true
end

#_zoidberg_free_workerObject

Find or wait for a free worker

Returns:

  • (Object)


88
89
90
91
92
93
# File 'lib/zoidberg/pool.rb', line 88

def _zoidberg_free_worker
  until(worker = @_workers.detect(&:_zoidberg_available?))
    defer{ _signal.wait_for(:unlocked) }
  end
  worker
end

#terminateObject

Force termination of all workers when terminated



96
97
98
# File 'lib/zoidberg/pool.rb', line 96

def terminate
  @_workers.map(&:_zoidberg_destroy!)
end