Coverage for ion/core/cc/container : 78.29%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
|
#!/usr/bin/env python
@author Dorian Raymer @author Michael Meisinger @brief Capability Container main class @see http://www.oceanobservatories.org/spaces/display/syseng/CIAD+COI+SV+Python+Capability+Container
A container utilizes the messaging abstractions for AMQP.
"""
""" Represents an instance of the Capability Container. Typically, in one Twisted process (= one UNIX process), there is only one instance of a CC. In test cases, however, there might be more. """
# Static variables # Generate unique container id (and process id prefix). Avoid . chars.
# Config instance
# ExchangeManager instance
# ProcessManager instance
# AppManager instance
# InterceptorSystem
def on_initialize(self, config, *args, **kwargs): """ Initializes the instance of a container. Actions include - Receive and parse the configuration - Prepare some active objects """
# Set additional container args
def on_activate(self, *args, **kwargs): """ Activates the container. Actions include - Initiate broker connection - Start @retval Deferred """
## Lifecycle event publishing disabled for now # now that we've activated, can publish ContainerLifecycleEvents as we need the exchange_manager in place. # this is the first chance we have to construct this publisher though. #p = Process(spawnargs={'proc-name': 'ContainerLCEPubProcess'}) #yield p.spawn()
#self._lc_pub = ContainerLifecycleEventPublisher(origin=self.id, process=p) #yield self._lc_pub.initialize() #yield self._lc_pub.activate()
# now publish the event #yield self._lc_pub.create_and_publish_event(state=ContainerLifecycleEventPublisher.State.ACTIVE)
raise NotImplementedError("Not implemented")
def on_terminate(self, *args, **kwargs): """ Deactivates and terminates the container. Actions include - Stop and terminate all container applications - Close broker connection @retval Deferred """
# technically this is not correct as we're still not quite TERMINATED, but for all intents and purposes.. # we have to publish before we tear down the messaging framework #yield self._lc_pub.create_and_publish_event(state=self._lc_pub.State.TERMINATED) #yield self._lc_pub.terminate() #yield self._lc_pub._process.terminate()
log.info("Container terminating hard due to fatal error!") yield defer.succeed(None) defer.returnValue(None)
"""An error here is always fatal. """ #raise RuntimeError("Illegal state change for container") self.fatalError()
# --- Container API -----------
# Process management, handled by ProcessManager return self.proc_manager.activate_process(*args, **kwargs)
# Exchange management, handled by ExchangeManager return self.exchange_manager.configure_messaging(*args, **kwargs)
# App management, handled by AppManager # Release management, handled by AppManager return self.app_manager.start_rel(*args, **kwargs)
# Container Events
""" Container event that componenets/processes can raise when something goes really wrong. The result of the fatalError can cause the whole container to shutdown by calling reactor.stop reactor.stop will call stopService on CapabilityContainer Service which, in turn, will terminate this container lifecycleobject, which then terminates its lifecycle objects. """ log.error('fatalError event') log.error(str(ex)) try: f = failure.Failure() log.info("The container suffered a fatal error event and is crashing.") log.debug(str(f.getTraceback())) f.printDetailedTraceback() log.info("The last traceback, in full detail, was written to stdout and the debug loglevel.") except failure.NoCurrentExceptionError: log.info("No Exception to be logged for fatalError")
if not self._fatal_error_encountered: ioninit.shutdown_or_die(30) # let's see what tenacious containers think of this little number self._fatal_error_encountered = True from twisted.internet import reactor tp = reactor.getThreadPool() for t in tp.working: t._Thread__stop() reactor.stop()
""" The exchange manager notifies the container when the amqp connection closes by triggering this event. The connection closure could be expected (if the exchange manager is terminated) or unexpected, indicating an error situation. """ log.info('exchangeConnectionLost %s' % (str(reason),)) self.fatalError(reason)
self._get_state(), self.exchange_manager.message_space)
""" Factory for a container. This also makes sure that only one container is active at any time, currently. """ raise RuntimeError('Already started')
|