import logging from xmlrpc.client import Fault as SupervisorFault from tfw.config import TFWENV from tfw.networking import Scope from tfw.components import ProcessManager, LogManager LOG = logging.getLogger(__name__) class ProcessManagingEventHandler(ProcessManager, LogManager): keys = ['processmanager'] """ Event handler that can manage processes managed by supervisor. This EventHandler accepts messages that have a data['command'] key specifying a command to be executed. Every message must contain a data['process_name'] field with the name of the process to manage. This is the name specified in supervisor config files like so: [program:someprogram] Commands available: start, stop, restart, readlog (the names are as self-documenting as it gets) """ def __init__(self, log_tail=0): ProcessManager.__init__(self, TFWENV.SUPERVISOR_HTTP_URI) LogManager.__init__(self, TFWENV.SUPERVISOR_HTTP_URI) self.log_tail = log_tail self.commands = { 'start': self.start_process, 'stop': self.stop_process, 'restart': self.restart_process } def handle_event(self, message, server_connector): try: data = message['data'] try: self.commands[data['command']](data['process_name']) except SupervisorFault as fault: message['data']['error'] = fault.faultString finally: message['data']['stdout'] = self.read_stdout( data['process_name'], self.log_tail ) message['data']['stderr'] = self.read_stderr( data['process_name'], self.log_tail ) server_connector.send_message(message, scope=Scope.WEBSOCKET) except KeyError: LOG.error('IGNORING MESSAGE: Invalid message received: %s', message)