module Celluloid module Internals # The Registry allows us to refer to specific actors by human-meaningful names class Registry def initialize @root = nil # keep root out of the standard list of registered names @actors = {} # hash of name => actor @index = {} # hash of name => branch @branches = {} # hash of branch => [ actors ] @registry = Mutex.new end # Register an Actor def []=(name, actor) if name == :root @registry.synchronize do @root = actor end else actor_singleton = class << actor; self; end raise TypeError, "not an actor" unless actor_singleton.ancestors.include? Proxy::Abstract # if actor.class.ancestors.include? Supervision::Container # puts "Supervisor: #{actor.links.inspect}" # end @registry.synchronize do @actors[name.to_sym] = actor end actor.mailbox << NamingRequest.new(name.to_sym) end end def add(name, actor, branch = :services) set(name, actor) @registry.synchronize do unless @branches.key? branch @branches[branch] = [] self.class.instance_eval do begin remove_method(branch) rescue nil end define_method(branch) { @branches[branch] } end @branches[branch] << name end @index[name.to_sym] = branch end end # Retrieve an actor by name def [](name) return @root if name == :root @registry.synchronize do @actors[name.to_sym] end end def branch(name) @registry.synchronize do @index.select { |_a, b| b == name } end end alias get [] alias set []= def delete(name) @registry.synchronize do @index.delete name.to_sym @actors.delete name.to_sym end end def include?(name) names.include? name end # List all registered actors by name def names @registry.synchronize { @actors.keys } end def index @registry.synchronize { @index } end # removes and returns all registered actors as a hash of `name => actor` # can be used in testing to clear the registry def clear hash = nil @registry.synchronize do hash = @actors.dup @actors.clear @index.clear end hash end end end end