Class: Roby::DRoby::ObjectManager

Inherits:
Object
  • Object
show all
Defined in:
lib/roby/droby/object_manager.rb

Overview

The object manager manages the IDs of an object among known peers

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(local_id) ⇒ ObjectManager

Returns a new instance of ObjectManager.



22
23
24
25
# File 'lib/roby/droby/object_manager.rb', line 22

def initialize(local_id)
    @local_id = local_id
    clear
end

Instance Attribute Details

#local_idPeerID (readonly)

The Peer ID of the local Roby instance

Returns:



10
11
12
# File 'lib/roby/droby/object_manager.rb', line 10

def local_id
  @local_id
end

#models_by_nameObject (readonly)

Resolution of models by name



20
21
22
# File 'lib/roby/droby/object_manager.rb', line 20

def models_by_name
  @models_by_name
end

#siblings_by_local_object_idObject (readonly)

Resolution of a remote DRobyID by first the object’s local ID and then the remote PeerID



14
15
16
# File 'lib/roby/droby/object_manager.rb', line 14

def siblings_by_local_object_id
  @siblings_by_local_object_id
end

#siblings_by_peerObject (readonly)

Mapping of known objects by peer and droby ID



17
18
19
# File 'lib/roby/droby/object_manager.rb', line 17

def siblings_by_peer
  @siblings_by_peer
end

Instance Method Details

#clearObject



27
28
29
30
31
# File 'lib/roby/droby/object_manager.rb', line 27

def clear
    @siblings_by_peer = Hash.new { |h, k| h[k] = {} }
    @siblings_by_local_object_id = Hash.new { |h, k| h[k] = {} }
    @models_by_name = {}
end

#deregister_object(local_object) ⇒ Object

Deregisters a mapping from object IDs to a particular object



150
151
152
153
154
155
156
157
158
159
160
# File 'lib/roby/droby/object_manager.rb', line 150

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)
        n = local_object.name
        models_by_name.delete(n) if local_object == models_by_name[n]
    end
end

#deregister_siblings(local_object, siblings) ⇒ Object

Deregisters siblings of a known local object

If the object has no known siblings left, it is also deregistered



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/roby/droby/object_manager.rb', line 119

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

#fetch_by_id(peer_id, droby_id) ⇒ Object



39
40
41
42
43
44
45
# File 'lib/roby/droby/object_manager.rb', line 39

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

#find_by_id(peer_id, droby_id) ⇒ Object



33
34
35
36
37
# File 'lib/roby/droby/object_manager.rb', line 33

def find_by_id(peer_id, droby_id)
    if object_siblings = siblings_by_peer.fetch(peer_id, nil)
        object_siblings[droby_id]
    end
end

#find_model_by_name(name) ⇒ Object?

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

Parameters:

  • name (String)

    the name of the model to resolve

Returns:



181
182
183
# File 'lib/roby/droby/object_manager.rb', line 181

def find_model_by_name(name)
    models_by_name[name]
end

#include?(local_object) ⇒ Boolean

Tests whether self knows about a local object

Returns:

  • (Boolean)


98
99
100
# File 'lib/roby/droby/object_manager.rb', line 98

def include?(local_object)
    siblings_by_local_object_id.has_key?(local_object.droby_id)
end

#known_sibling_on(local_object, peer_id) ⇒ DRobyID?

The ID this object is known for on the given peer

Parameters:

  • local_object (#droby_id)
  • peer_id (PeerID)

    the ID of our peer

Returns:



65
66
67
68
69
70
71
72
73
# File 'lib/roby/droby/object_manager.rb', line 65

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

#known_siblings_for(object) ⇒ Hash

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

Parameters:

Returns:

  • (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



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/roby/droby/object_manager.rb', line 85

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
        {}
    end
end

#pretty_print(pp) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/roby/droby/object_manager.rb', line 185

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_model(local_object, known_siblings = {}, name: local_object.name) ⇒ Object

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



167
168
169
170
# File 'lib/roby/droby/object_manager.rb', line 167

def register_model(local_object, known_siblings = {}, name: local_object.name)
    models_by_name[name] = local_object if name
    register_object(local_object, known_siblings)
end

#register_object(local_object, known_siblings = {}) ⇒ Object

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



144
145
146
147
# File 'lib/roby/droby/object_manager.rb', line 144

def register_object(local_object, known_siblings = {})
    register_siblings(local_object, local_id => local_object.droby_id)
    register_siblings(local_object, known_siblings)
end

#register_siblings(local_object, siblings) ⇒ Object

Registers siblings for a local object

Unlike #register_object, it does not automatically adds the local mapping to the set of known siblings



106
107
108
109
110
111
112
113
# File 'lib/roby/droby/object_manager.rb', line 106

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

#registered_sibling_on(local_object, peer_id) ⇒ DRobyID?

The registered ID for this object on a given peer

Parameters:

  • local_object (#droby_id)
  • peer_id (PeerID)

    the ID of our peer

Returns:



52
53
54
55
56
57
58
# File 'lib/roby/droby/object_manager.rb', line 52

def registered_sibling_on(local_object, peer_id)
    return unless local_object.respond_to?(:droby_id)

    siblings =
        siblings_by_local_object_id.fetch(local_object.droby_id, nil)
    siblings[peer_id] if siblings
end

#statObject



202
203
204
205
206
# File 'lib/roby/droby/object_manager.rb', line 202

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