exit_handler monkeypatch for pool
module Celluloid
module Supervision
class Container
# Manages a fixed-size pool of actors
# Delegates work (i.e. methods) and supervises actors
# Don't use this class directly. Instead use MyKlass.pool
class Pool
def initialize(options={})
@idle = []
@busy = []
@klass = options[:actors]
@actors = Set.new
@mutex = Mutex.new
@size = options[:size] || [Celluloid.cores || 2, 2].max
@args = options[:args] ? Array(options[:args]) : []
@exit_handler = options[:exit_handler]
# Do this last since it can suspend and/or crash
@idle = @size.times.map { __spawn_actor__ }
end
# Spawn a new worker for every crashed one
def __crash_handler__(actor, reason)
@mutex.synchronize {
@busy.delete actor
@idle.delete actor
@actors.delete actor
}
@exit_handler.call(actor, reason) if @exit_handler
return unless reason
@idle << __spawn_actor__
signal :respawn_complete
end
class << self
def pooling_options(config={},mixins={})
combined = { :type => Celluloid::Supervision::Container::Pool }.merge(config).merge(mixins)
combined[:args] = [[:block, :actors, :size, :args, :exit_handler].inject({}) { |e,p| e[p] = combined.delete(p) if combined[p]; e }]
combined
end
end
identifier! :size, :pool, :exit_handler
configuration do
@supervisor = Container::Pool
@method = "pool_link"
@pool = true
@pool_size = @configuration[:size]
@exit_handler = @configuration[:exit_handler]
@configuration
end
end
end
end
end