class Roby::DRoby::ObjectManager
The object manager manages the IDs of an object among known peers
Attributes
The Peer ID of the local Roby
instance
@return [PeerID]
Resolution of models by name
Resolution of a remote DRobyID by first the object's local ID and then the remote PeerID
Mapping of known objects by peer and droby ID
Public Class Methods
# File lib/roby/droby/object_manager.rb, line 20 def initialize(local_id) @local_id = local_id clear end
Public Instance Methods
# File lib/roby/droby/object_manager.rb, line 25 def clear @siblings_by_peer = Hash.new { |h, k| h[k] = Hash.new } @siblings_by_local_object_id = Hash.new { |h, k| h[k] = Hash.new } @models_by_name = Hash.new end
Deregisters a mapping from object IDs to a particular object
# File lib/roby/droby/object_manager.rb, line 142 def deregister_object(local_object) siblings = siblings_by_local_object_id.delete(local_object.droby_id) siblings.each do |peer_id, droby_id| siblings_by_peer[peer_id].delete(droby_id) end if local_object.respond_to?(:name) if local_object == models_by_name[n = local_object.name] models_by_name.delete(n) end end end
Deregisters siblings of a known local object
If the object has no known siblings left, it is also deregistered
# File lib/roby/droby/object_manager.rb, line 115 def deregister_siblings(local_object, siblings) local_object_id = local_object.droby_id object_siblings = siblings_by_local_object_id[local_object_id] siblings.each do |peer_id, droby_id| if actual_droby_id = object_siblings.delete(peer_id) if actual_droby_id != droby_id raise ArgumentError, "DRobyID of #{local_object} on #{peer_id} mismatches between provided #{droby_id} and registered #{actual_droby_id}" end siblings_by_peer[peer_id].delete(droby_id) end end if object_siblings.empty? deregister_object(local_object) end end
# File lib/roby/droby/object_manager.rb, line 37 def fetch_by_id(peer_id, droby_id) if local_object = find_by_id(peer_id, droby_id) local_object else raise UnknownSibling, "there is no known object for #{droby_id}@#{peer_id.inspect} on #{self}" end end
# File lib/roby/droby/object_manager.rb, line 31 def find_by_id(peer_id, droby_id) if object_siblings = siblings_by_peer.fetch(peer_id, nil) object_siblings[droby_id] end end
Attempts to resolve a registered model by its name
In addition to ID-based resolution, models registered with {#register_model} can also be resolved by name.
This attempts a name-based resolution
@param [String] name the name of the model to resolve @return [Object,nil]
# File lib/roby/droby/object_manager.rb, line 176 def find_model_by_name(name) models_by_name[name] end
Tests whether self knows about a local object
# File lib/roby/droby/object_manager.rb, line 94 def include?(local_object) siblings_by_local_object_id.has_key?(local_object.droby_id) end
The ID this object is known for on the given peer
@param [#droby_id] local_object @param [PeerID] peer_id the ID of our peer @return [DRobyID,nil]
# File lib/roby/droby/object_manager.rb, line 63 def known_sibling_on(local_object, peer_id) if local_object.respond_to?(:droby_id) if siblings = siblings_by_local_object_id.fetch(local_object.droby_id, nil) siblings[peer_id] elsif peer_id == local_id local_object.droby_id end end end
The set of IDs known for this object
This returns a mapping from peer IDs to the ID of the provided object on this peer. The list of siblings is maintained by {#register_object} and {#deregister_object}
@param [Object] object @return [Hash] the siblings. A hash that announces the local ID is
returned if the object is not registered, and an empty hash if it is not DRoby-addressable
# File lib/roby/droby/object_manager.rb, line 83 def known_siblings_for(object) if object.respond_to?(:droby_id) if siblings = siblings_by_local_object_id.fetch(object.droby_id, nil) siblings else Hash[local_id => object.droby_id] end else Hash.new end end
# File lib/roby/droby/object_manager.rb, line 180 def pretty_print(pp) pp.text "Object manager with local ID=#{local_id}" pp.nest(2) do pp.breakable pp.text "Registered objects" siblings_by_peer.each do |peer_id, siblings| siblings.each do |peer_object_id, object| pp.breakable pp.text " #{peer_object_id}@#{peer_id} " pp.nest(4) do object.pretty_print(pp) end end end end end
Register a model by name and a list of known siblings for it
In addition to ID-based resolution, models can also be resolved by name through {#find_model_by_name}. This registers the name mapping and then calls {#register_object}
# File lib/roby/droby/object_manager.rb, line 160 def register_model(local_object, known_siblings = Hash.new, name: local_object.name) if name models_by_name[name] = local_object end register_object(local_object, known_siblings) end
Registers the mappings from object IDs to the corresponding local object
This registers the mapping for the local process (local_id
=> local_object.droby_id), along with known siblings if provided
# File lib/roby/droby/object_manager.rb, line 136 def register_object(local_object, known_siblings = Hash.new) register_siblings(local_object, local_id => local_object.droby_id) register_siblings(local_object, known_siblings) end
Registers siblings for a local object
Unlike {#register_object}, it does not automatically adds the local mapping to the set of known siblings
# File lib/roby/droby/object_manager.rb, line 102 def register_siblings(local_object, siblings) local_object_id = local_object.droby_id siblings.each do |peer_id, droby_id| siblings_by_peer[peer_id][droby_id] = local_object end siblings_by_local_object_id[local_object_id]. merge!(siblings) end
The registered ID for this object on a given peer
@param [#droby_id] local_object @param [PeerID] peer_id the ID of our peer @return [DRobyID,nil]
# File lib/roby/droby/object_manager.rb, line 50 def registered_sibling_on(local_object, peer_id) if local_object.respond_to?(:droby_id) if siblings = siblings_by_local_object_id.fetch(local_object.droby_id, nil) siblings[peer_id] end end end
# File lib/roby/droby/object_manager.rb, line 197 def stat Hash[siblings_by_local_object_id: siblings_by_local_object_id.size, models_by_name: models_by_name.size, siblings_by_peer: siblings_by_peer.inject(0) { |sum, (_, siblings)| sum += siblings.size }] end