manager.py
Go to the documentation of this file.
1 # -*- Python -*-
2 # -*- coding: utf-8 -*-
3 
4 '''rtctree
5 
6 Copyright (C) 2009-2014
7  Geoffrey Biggs
8  RT-Synthesis Research Group
9  Intelligent Systems Research Institute,
10  National Institute of Advanced Industrial Science and Technology (AIST),
11  Japan
12  All rights reserved.
13 Licensed under the Eclipse Public License -v 1.0 (EPL)
14 http://www.opensource.org/licenses/eclipse-1.0.txt
15 
16 Object representing a manager node in the tree.
17 
18 '''
19 
20 
21 from omniORB import CORBA, TRANSIENT_ConnectFailed, UNKNOWN_UserException
22 import os.path
23 import sys
24 
25 from rtctree.component import Component
26 from rtctree.exceptions import FailedToLoadModuleError, \
27  FailedToCreateComponentError, \
28  FailedToDeleteComponentError, \
29  FailedToSetConfigurationError, \
30  FailedToAddMasterManagerError, \
31  FailedToRemoveMasterManagerError, \
32  FailedToAddSlaveManagerError, \
33  FailedToRemoveSlaveManagerError
34 from rtctree.node import TreeNode
35 from rtctree.utils import nvlist_to_dict
36 import RTC
37 
38 
39 ##############################################################################
40 ## Manager node object
41 
43  '''Node representing a manager on a name server.
44 
45  Manager nodes can occur below name server and directory nodes. They may
46  store child components and child managers. They can be used to add and
47  remove new components and managers to the tree at run time.
48 
49  '''
50  def __init__(self, name=None, parent=None, obj=None, *args, **kwargs):
51  '''Constructor. Calls the TreeNode constructor.'''
52  super(Manager, self).__init__(name=name, parent=parent, *args,
53  **kwargs)
54  self._obj = obj
55  self._parse()
56 
57  ##########################################################################
58  # Module and component management
59 
60  def create_component(self, module_name):
61  '''Create a component out of a loaded module.
62 
63  Turns a previously-loaded shared module into a component in the
64  manager. This will invalidate any objects that are children of this
65  node.
66 
67  The @ref module_name argument can contain options that set various
68  properties of the new component. These must be appended to the module
69  name, prefixed by a question mark for each property, in key=value
70  format. For example, to change the instance name of the new component,
71  append '?instance_name=new_name' to the module name.
72 
73  @param module_name Name of the module to turn into a component.
74  @raises FailedToCreateComponentError
75 
76  '''
77  with self._mutex:
78  if not self._obj.create_component(module_name):
79  raise FailedToCreateComponentError(module_name)
80  # The list of child components will have changed now, so it must be
81  # reparsed.
83 
84  def delete_component(self, instance_name):
85  '''Delete a component.
86 
87  Deletes the component specified by @ref instance_name from the manager.
88  This will invalidate any objects that are children of this node.
89 
90  @param instance_name The instance name of the component to delete.
91  @raises FailedToDeleteComponentError
92 
93  '''
94  with self._mutex:
95  if self._obj.delete_component(instance_name) != RTC.RTC_OK:
96  raise FailedToDeleteComponentError(instance_name)
97  # The list of child components will have changed now, so it must be
98  # reparsed.
100 
101  def load_module(self, path, init_func):
102  '''Load a shared library.
103 
104  Call this function to load a shared library (DLL file under Windows,
105  shared object under UNIX) into the manager.
106 
107  @param path The path to the shared library.
108  @param init_func The name entry function in the library.
109  @raises FailedToLoadModuleError
110 
111  '''
112  try:
113  with self._mutex:
114  if self._obj.load_module(path, init_func) != RTC.RTC_OK:
115  raise FailedToLoadModuleError(path)
116  except CORBA.UNKNOWN, e:
117  if e.args[0] == UNKNOWN_UserException:
118  raise FailedToLoadModuleError(path, 'CORBA User Exception')
119  else:
120  raise
121 
122  def unload_module(self, path):
123  '''Unload a loaded shared library.
124 
125  Call this function to remove a shared library (e.g. a component) that
126  was previously loaded.
127 
128  @param path The path to the shared library.
129  @raises FailedToUnloadModuleError
130 
131  '''
132  with self._mutex:
133  if self._obj.unload_module(path) != RTC.RTC_OK:
134  raise FailedToUnloadModuleError(path)
135 
136  @property
137  def components(self):
138  '''The list of components in this manager, if any.
139 
140  This information can also be found by listing the children of this node
141  that are of type @ref Component. That method is more useful as it returns
142  the tree entries for the components.
143 
144  '''
145  with self._mutex:
146  if not self._components:
147  self._components = [c for c in self.children if c.is_component]
148  return self._components
149 
150  @property
151  def factory_profiles(self):
152  '''The factory profiles of all loaded modules.'''
153  with self._mutex:
154  if not self._factory_profiles:
156  for fp in self._obj.get_factory_profiles():
157  self._factory_profiles.append(nvlist_to_dict(fp.properties))
158  return self._factory_profiles
159 
160  ##########################################################################
161  # Manager configuration
162 
163  def set_config_parameter(self, param, value):
164  '''Set a configuration parameter of the manager.
165 
166  @param The parameter to set.
167  @value The new value for the parameter.
168  @raises FailedToSetConfigurationError
169 
170  '''
171  with self._mutex:
172  if self._obj.set_configuration(param, value) != RTC.RTC_OK:
173  raise FailedToSetConfigurationError(param, value)
174  # Force a reparse of the configuration
175  self._configuration = None
176 
177  @property
178  def configuration(self):
179  '''The configuration dictionary of the manager.'''
180  with self._mutex:
181  if not self._configuration:
182  self._configuration = nvlist_to_dict(self._obj.get_configuration())
183  return self._configuration
184 
185  @property
186  def profile(self):
187  '''The manager's profile.'''
188  with self._mutex:
189  if not self._profile:
190  profile = self._obj.get_profile()
191  self._profile = nvlist_to_dict(profile.properties)
192  return self._profile
193 
194  ##########################################################################
195  # Undocumented functions
196 
197  def fork(self):
198  '''Fork the manager.'''
199  with self._mutex:
200  self._obj.fork()
201 
202  def shutdown(self):
203  '''Shut down the manager.'''
204  with self._mutex:
205  self._obj.shutdown()
206 
207  def restart(self):
208  '''Restart the manager.'''
209  with self._mutex:
210  self._obj.restart()
211 
212  ##########################################################################
213  # Node functionality
214 
215  @property
216  def is_directory(self):
217  '''Is this node a directory?'''
218  return True
219 
220  @property
221  def is_manager(self):
222  '''Is this node a manager?'''
223  return True
224 
225 
226  @property
227  def object(self):
228  '''The RTM::Manager object that this node contains.'''
229  with self._mutex:
230  return self._obj
231 
232  @property
233  def is_master(self):
234  '''Is this manager node a master manager?
235 
236  Master managers have a direct presence on the name server. Slave
237  managers are only present as children of other managers.
238 
239  '''
240  with self._mutex:
241  return self._obj.is_master()
242 
243  @property
244  def loadable_modules(self):
245  '''The list of loadable module profile dictionaries.'''
246  with self._mutex:
247  if not self._loadable_modules:
249  for mp in self._obj.get_loadable_modules():
250  self._loadable_modules.append(nvlist_to_dict(mp.properties))
251  return self._loadable_modules
252 
253  @property
254  def loaded_modules(self):
255  '''The list of loaded module profile dictionaries.'''
256  with self._mutex:
257  if not self._loaded_modules:
258  self._loaded_modules = []
259  for mp in self._obj.get_loaded_modules():
260  self._loaded_modules.append(nvlist_to_dict(mp.properties))
261  return self._loaded_modules
262 
263  @property
264  def masters(self):
265  '''The list of master managers of this manager, if any.
266 
267  If this manager is a master, this list will be empty.
268 
269  '''
270  with self._mutex:
271  if not self._masters:
272  raise NotImplementedError
273  return self._masters
274 
275  @property
276  def slaves(self):
277  '''The list of slave managers of this manager, if any.
278 
279  This information can also be found by listing the children of this node
280  that are of type @ref Manager.
281 
282  '''
283  with self._mutex:
284  if not self._slaves:
285  self._slaves = [c for c in self.children if c.is_manager]
286  return self._slaves
287 
288  ##########################################################################
289  # Internal functions
290 
291  def _add_master(self, new_master):
292  # Add a new master to this manager. A slave manager can have multiple
293  # masters. new_master should be a rtctree.manager.Manager object.
294  with self._mutex:
295  if self._obj.add_master_manager(new_master.object) != RTC.RTC_OK:
296  raise FailedToAddMasterManagerError
297 
298  def _add_slave(self, new_slave):
299  # Add a slave to this manager. Master managers can hold slave managers,
300  # which appear as child nodes in the tree. It will appear in the tree
301  # as a new child node of this manager's node if the tree is reparsed.
302  # new_slave should be a rtctree.manager.Manager object.
303  with self._mutex:
304  if self._obj.add_save_manager(new_slave.object) != RTC.RTC_OK:
305  raise FailedToAddSlaveManagerError(self.name, new_slave.name)
306 
307  def _parse(self):
308  # Nearly everything is delay-parsed when it is first accessed.
309  with self._mutex:
310  self._components = None
311  self._configuration = None
312  self._profile = None
313  self._factory_profiles = None
314  self._loadable_modules = None
315  self._loaded_modules = None
316  self._masters = None
317  self._slaves = None
318  self._parse_children()
319 
320  def _parse_children(self):
321  # Parses child managers and components.
322  with self._mutex:
325 
327  # Parses the list returned by _obj.get_components into child nodes.
328  with self._mutex:
329  try:
330  comps = self._obj.get_components()
331  except CORBA.BAD_PARAM, e:
332  print >>sys.stderr, '{0}: {1}'.format(
333  os.path.basename(sys.argv[0]), e)
334  return
335  for c in comps:
336  # Get the instance profile - this will be the node's name
337  profile = c.get_component_profile()
338  instance_name = profile.instance_name
339  # Create and store the new leaf node
340  leaf = Component(instance_name + '.rtc', self, c)
341  self._add_child(leaf)
342 
344  # Parses the list returned by _obj.get_slave_managers into child nodes.
345  with self._mutex:
346  try:
347  mgrs = self._obj.get_slave_managers()
348  except CORBA.BAD_OPERATION:
349  # This manager does not support slave managers; ignore
350  return
351  index = 0
352  for m in mgrs:
353  # Add each slave manager as a child node.
354  try:
355  props = nvlist_to_dict(m.get_profile().properties)
356  except CORBA.TRANSIENT, e:
357  if e.args[0] == TRANSIENT_ConnectFailed:
358  print >>sys.stderr, '{0}: Warning: zombie slave of '\
359  'manager {1} found'.format(sys.argv[0],
360  self.name)
361  continue
362  else:
363  raise
364  if 'name' in props:
365  name = props['name']
366  else:
367  name = 'slave{0}'.format(index)
368  index += 1
369  leaf = Manager(name, self, m)
370  self._add_child(leaf)
371 
372  def _remove_master(self, master):
373  # Remove a new master from this manager. A slave manager can have multiple
374  # masters. new_master should be a rtctree.manager.Manager object.
375  with self._mutex:
376  if self._obj.remove_master_manager(master.object) != RTC.RTC_OK:
377  raise FailedToRemoveMasterManagerError
378 
379  def _remove_slave(self, slave):
380  # Remove a slave from this manager. Master managers can hold slave
381  # managers, which appear as child nodes in the tree. slave should be a
382  # rtctree.manager.Manager object.
383  with self._mutex:
384  if self._obj.remove_slave_manager(slave.object) != RTC.RTC_OK:
385  raise FailedToRemoveSlaveManagerError(self.name, slave.name)
386 
387  def _set_parent(self, new_parent):
388  # When setting the parent of a manager node, we need to tell wrapped
389  # object that it has a new master. If our old parent was a master, then
390  # we need to remove ourselves from that one.
391  # Note that rtctree assumes a singly-linked hierarchy of managers.
392  with self._mutex:
393  if self.parent:
394  if self.parent.is_manager:
395  self.parent._remove_slave(self)
396  self._remove_master(self.parent)
397  self._add_master(new_parent)
398  new_parent._add_slave(self)
399  self.parent = new_parent
400 
401 
402 # vim: tw=79
403 
def children(self)
Definition: node.py:196
def _parse_manager_children(self)
Definition: manager.py:343
def _add_master(self, new_master)
Internal functions.
Definition: manager.py:291
def __init__(self, name=None, parent=None, obj=None, args, kwargs)
Definition: manager.py:50
def _parse_children(self)
Definition: manager.py:320
Component node object.
Definition: component.py:38
def name(self)
Definition: node.py:291
def _add_slave(self, new_slave)
Definition: manager.py:298
def unload_module(self, path)
Definition: manager.py:122
def loadable_modules(self)
Definition: manager.py:244
def load_module(self, path, init_func)
Definition: manager.py:101
def fork(self)
Undocumented functions.
Definition: manager.py:197
def components(self)
Definition: manager.py:137
def create_component(self, module_name)
Module and component management.
Definition: manager.py:60
def factory_profiles(self)
Definition: manager.py:151
def configuration(self)
Definition: manager.py:178
def _add_child(self, new_child)
Definition: node.py:360
def loaded_modules(self)
Definition: manager.py:254
def _remove_slave(self, slave)
Definition: manager.py:379
def _remove_master(self, master)
Definition: manager.py:372
Manager node object.
Definition: manager.py:42
def _parse_component_children(self)
Definition: manager.py:326
Base node object.
Definition: node.py:29
def nvlist_to_dict(nvlist)
Definition: utils.py:169
def delete_component(self, instance_name)
Definition: manager.py:84
def is_directory(self)
Node functionality.
Definition: manager.py:216
def set_config_parameter(self, param, value)
Manager configuration.
Definition: manager.py:163
def is_manager(self)
Definition: manager.py:221
def _set_parent(self, new_parent)
Definition: manager.py:387


rtctree
Author(s): Geoffrey Biggs
autogenerated on Fri Jun 7 2019 21:56:24