Package elisa :: Package core :: Module manager
[hide private]
[frames] | no frames]

Source Code for Module elisa.core.manager

  1  # -*- coding: utf-8 -*- 
  2  # Elisa - Home multimedia server 
  3  # Copyright (C) 2006-2008 Fluendo Embedded S.L. (www.fluendo.com). 
  4  # All rights reserved. 
  5  # 
  6  # This file is available under one of two license agreements. 
  7  # 
  8  # This file is licensed under the GPL version 3. 
  9  # See "LICENSE.GPL" in the root of this distribution including a special 
 10  # exception to use Elisa with Fluendo's plugins. 
 11  # 
 12  # The GPL part of Elisa is also available under a commercial licensing 
 13  # agreement from Fluendo. 
 14  # See "LICENSE.Elisa" in the root directory of this distribution package 
 15  # for details on that license. 
 16   
 17  """ 
 18  Component instances management 
 19  """ 
 20   
 21   
 22  __maintainer__ = 'Philippe Normand <philippe@fluendo.com>' 
 23   
 24  from elisa.core import log 
 25  from elisa.core.component import ComponentError 
 26  from elisa.core.plugin_registry import ComponentNotFound 
 27  from elisa.core.utils import classinit 
 28  from elisa.core import common 
 29  from twisted.internet import defer, task 
 30   
31 -class AlreadyRegistered(Exception):
32 pass
33
34 -class CannotUnregister(Exception):
35 pass
36
37 -class Manager(log.Loggable):
38 """ A Manager is a Component container 39 40 Components can be registered and unregistered from the 41 Manager. 42 43 Optionnally the manager can implement start/stop methods if it 44 needs to handle any kind of loop (example: media sources scanning, 45 input events polling, etc). start/stop methods are called by the 46 parent object (application). 47 48 @ivar _components: Components currently registered in the manager 49 @type _components: L{elisa.core.component.Component} list 50 """ 51 52 # Allows property fget/fset/fdel/doc overriding 53 __metaclass__ = classinit.ClassInitMeta 54 __classinit__ = classinit.build_properties 55
56 - def __init__(self):
57 """ Initialize the _components instance variable and the 58 Manager as a Loggable object. 59 """ 60 log.Loggable.__init__(self) 61 self.debug("Creating") 62 63 self._components = []
64
65 - def initialize(self):
66 """ 67 This function is called when the application has initialized completely 68 """ 69 return self._load_providers()
70
71 - def _load_providers(self):
72 """ Ask the plugin registry to create all the providers 73 components defined in section 'general' of the config 74 """ 75 # FIXME: not a very clean way to deduce *_providers from *_manager 76 providers_type = self.name[:-8] + "_providers" 77 application = common.application 78 providers_names = application.config.get_option(providers_type, 79 section='general', 80 default=[]) 81 82 plugin_registry = application.plugin_registry 83 84 def load_providers_iter(loaded): 85 def create_component_done(component): 86 self.log("Loaded provider %s" % component.name) 87 self.register_component(component) 88 loaded.append(component) 89 90 return component
91 92 def create_component_failure(failure): 93 if isinstance(failure.value, (ComponentError, 94 ComponentNotFound)): 95 self.warning(failure.getErrorMessage()) 96 else: 97 try: 98 failure.raiseException() 99 except: 100 common.application.handle_traceback() 101 102 # continue 103 return
104 105 for provider_name in providers_names: 106 res = defer.maybeDeferred(plugin_registry.create_component, 107 provider_name) 108 res.addCallback(create_component_done) 109 res.addErrback(create_component_failure) 110 111 yield res 112 113 def load_providers_iter_done(iter, loaded): 114 self.debug("Loaded %s %s" % (len(loaded), providers_type)) 115 116 return self 117 118 loaded = [] 119 res_dfr = task.coiterate(load_providers_iter(loaded)) 120 res_dfr.addCallback(load_providers_iter_done, loaded) 121 122 return res_dfr 123
124 - def start(self):
125 """ Start a loop or something to initialize the Manager. Can 126 also look for new components to register in this method. 127 128 Does nothing by default, override if needed. 129 """
130
131 - def stop(self):
132 """ Stop clean and remove all registered components. 133 134 @rtype: L{twisted.internet.defer.DeferredList} 135 """ 136 deferreds = [] 137 for component in self._components: 138 deferreds.append(defer.maybeDeferred(component.clean)) 139 self._components = [] 140 141 return defer.DeferredList(deferreds)
142
143 - def component_registered(self, component):
144 """ Check if a component is registed in the Manager or not 145 146 @param component: the Component to register 147 @type component: L{elisa.core.component.Component} 148 @rtype: bool 149 """ 150 return component in self._components
151
152 - def register_component(self, component):
153 """ Register a new Component 154 155 Store a new Component in our components list. Returns the 156 result of the operation. If the component is already 157 registered, don't register it twice. 158 159 @param component: the Component to register 160 @type component: L{elisa.core.component.Component} 161 162 @raise AlreadyRegistered : when the component has already been registered 163 """ 164 165 if not self.component_registered(component): 166 self.debug("Registering component %s" % component.path) 167 self._components.append(component) 168 else: 169 self.debug("Component %s already registered" % component.path) 170 raise AlreadyRegistered()
171 172
173 - def unregister_component(self, component):
174 """ Unregister a component from the Manager 175 176 Remove the Component instance from our components list if it's 177 there. Returns the result of the operation. 178 179 @param component: the Component to register 180 @type component: L{elisa.core.component.Component} 181 182 @raise CannotUnregister : raised when the component cannot be removed 183 """ 184 185 if self.component_registered(component): 186 self.debug("Unregistering component %s" % component.path) 187 self._components.remove(component) 188 else: 189 self.debug("Impossible to unregister component %s" % component.path) 190 raise CannotUnregister()
191