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



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

def initialize(local_id)
    @local_id = local_id
    clear
end

Instance Attribute Details

#local_idPeerID (readonly)

The Peer ID of the local Roby instance



8
9
10
# File 'lib/roby/droby/object_manager.rb', line 8

def local_id
  @local_id
end

#models_by_nameObject (readonly)

Resolution of models by name



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

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



12
13
14
# File 'lib/roby/droby/object_manager.rb', line 12

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



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

def siblings_by_peer
  @siblings_by_peer
end

Instance Method Details

#clearObject



25
26
27
28
29
# 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

#deregister_object(local_object) ⇒ Object

Deregisters a mapping from object IDs to a particular object



142
143
144
145
146
147
148
149
150
151
152
153
# 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

#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



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# 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

#fetch_by_id(peer_id, droby_id) ⇒ Object



37
38
39
40
41
42
43
# 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

#find_by_id(peer_id, droby_id) ⇒ Object



31
32
33
34
35
# 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

#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



176
177
178
# File 'lib/roby/droby/object_manager.rb', line 176

def find_model_by_name(name)
    models_by_name[name]
end

#include?(local_object) ⇒ Boolean

Tests whether self knows about a local object



94
95
96
# 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

#known_sibling_on(local_object, peer_id) ⇒ DRobyID?

The ID this object is known for on the given peer



63
64
65
66
67
68
69
70
71
# 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

#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



83
84
85
86
87
88
89
90
91
# 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

#pretty_print(pp) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# 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_model(local_object, known_siblings = Hash.new, 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



160
161
162
163
164
165
# 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

#register_object(local_object, known_siblings = Hash.new) ⇒ 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



136
137
138
139
# 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

#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



102
103
104
105
106
107
108
109
# 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

#registered_sibling_on(local_object, peer_id) ⇒ DRobyID?

The registered ID for this object on a given peer



50
51
52
53
54
55
56
# 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

#statObject



197
198
199
200
201
# 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