def __init__(self, name, level_logger=logging.WARNING, timeout=None): """ Initialization and start of the process. :param str name: unique name that will be used to indentify the actor processus :param int level_logger: Define the level of the logger :param int timeout: if define, do something if no msg is recv every timeout (in ms) """ multiprocessing.Process.__init__(self, name=name) #: (logging.Logger): Logger self.logger = logging.getLogger(name) self.logger.setLevel(level_logger) formatter = logging.Formatter( '%(asctime)s || %(levelname)s || ' + '%(process)d %(processName)s || %(message)s') handler = logging.StreamHandler() handler.setFormatter(formatter) # file logger #handlerf = logging.FileHandler('powerapi.log') #handlerf.setLevel(level_logger) #handlerf.setFormatter(formatter) self.logger.addHandler(handler) #self.logger.addHandler(handlerf) #: (smartwatts.actor.state.State): actor's state self.state = State(self._initial_behaviour, SocketInterface(name, timeout), self.logger)
def __init__(self, initial_behaviour, socket_interface, logger, formula_factory, route_table): """ :param func initial_behaviour: Function that define the initial_behaviour :param socket_interface: Communication interface of the actor :type socket_interface: powerapi.SocketInterface :param formula_factory: Factory for Formula creation. :type formula_factory: func((formula_id) -> powerapi.Formula) :param route_table: initialized route table :type route_table: powerapi.dispatcher.state.RouteTable """ State.__init__(self, initial_behaviour, socket_interface, logger) #: (dict): Store the formula by id self.formula_dict = {} #: (utils.Tree): Tree store of the formula for faster #: DispatchRule self.formula_tree = Tree() #: (func): Factory for formula creation self.formula_factory = formula_factory self.route_table = route_table
def __init__(self, actor, database, report_model): """ :param BaseDB database: Database for saving data. """ State.__init__(self, actor) #: (BaseDB): Database for saving data. self.database = database #: (Report): Type of the report that the pusher handle. self.report_model = report_model #: (Dict): Buffer data. self.buffer = []
def __init__(self, behaviour, socket_interface, logger, database, report_filter, timeout_basic=0, timeout_sleeping=100): """ :param func behaviour: Function that define the initial_behaviour :param SocketInterface socket_interface: Communication interface of the actor :param BaseDB database: Allow to interact with a Database :param Filter report_filter: Filter of the Puller :param bool stream_mode: Puller stream_mode database. """ State.__init__(self, behaviour, socket_interface, logger) #: (BaseDB): Allow to interact with a Database self.database = database #: (it BaseDB): Allow to browse the database self.database_it = None #: (Filter): Filter of the puller self.report_filter = report_filter #: (bool): Puller stream_mode database. self.stream_mode = database.stream_mode #: (int): Timeout for "basic mode" self.timeout_basic = timeout_basic #: (int): Timeout for "sleeping mode" (allow to free the CPU) self.timeout_sleeping = timeout_sleeping #: (int): Counter for "sleeping mode" self.counter = 0
def __init__(self, name, push_socket_addr, level_logger=logging.WARNING, timeout=None): """ :param str name: Actor name :param int level_logger: Define logger level :param bool timeout: Time in millisecond to wait for a message before called timeout_handler. """ Actor.__init__(self, name, level_logger, timeout) #: (powerapi.State): Basic state of the Formula. self.state = State(self) self.addr = push_socket_addr self.push_socket = None
def __init__(self): Actor.__init__(self, 'test_supervisor') self.state = State(Mock()) self.send_msg = [] self.alive = False
def __init__(self): Actor.__init__(self, 'test_supervisor') self.state = State(Mock(), SocketInterface('test_supervisor', 0), Mock()) self.send_msg = [] self.alive = False
class Actor(multiprocessing.Process): """ Abstract class that exposes an interface to create, setup and handle actors :Method Interface: This table list from wich interface each methods are accessible +---------------------------------+--------------------------------------------------------------------------------------------+ | Interface type | method name | +=================================+============================================================================================+ | Client interface | :meth:`connect_data <powerapi.actor.actor.Actor.connect_data>` | | +--------------------------------------------------------------------------------------------+ | | :meth:`connect_control <powerapi.actor.actor.Actor.connect_control>` | | +--------------------------------------------------------------------------------------------+ | | :meth:`send_control <powerapi.actor.actor.Actor.send_control>` | | +--------------------------------------------------------------------------------------------+ | | :meth:`send_data <powerapi.actor.actor.Actor.send_data>` | +---------------------------------+--------------------------------------------------------------------------------------------+ | Server interface | :meth:`setup <powerapi.actor.actor.Actor.setup>` | | +--------------------------------------------------------------------------------------------+ | | :meth:`add_handler <powerapi.actor.actor.Actor.add_handler>` | +---------------------------------+--------------------------------------------------------------------------------------------+ :Attributes Interface: This table list from wich interface each attributes are accessible +---------------------------------+--------------------------------------------------------------------------------------------+ | Interface type | method name | +---------------------------------+--------------------------------------------------------------------------------------------+ | Server interface | :attr:`state <powerapi.actor.actor.Actor.state>` | +---------------------------------+--------------------------------------------------------------------------------------------+ """ def __init__(self, name, level_logger=logging.WARNING, timeout=None): """ Initialization and start of the process. :param str name: unique name that will be used to indentify the actor processus :param int level_logger: Define the level of the logger :param int timeout: if define, do something if no msg is recv every timeout (in ms) """ multiprocessing.Process.__init__(self, name=name) #: (logging.Logger): Logger self.logger = logging.getLogger(name) self.logger.setLevel(level_logger) formatter = logging.Formatter( '%(asctime)s || %(levelname)s || ' + '%(process)d %(processName)s || %(message)s') handler = logging.StreamHandler() handler.setFormatter(formatter) # file logger #handlerf = logging.FileHandler('powerapi.log') #handlerf.setLevel(level_logger) #handlerf.setFormatter(formatter) self.logger.addHandler(handler) #self.logger.addHandler(handlerf) #: (powerapi.State): Actor context self.state = State(self) #: (powerapi.SocketInterface): Actor's SocketInterface self.socket_interface = SocketInterface(name, timeout) #: (func): Actor behaviour self.behaviour = Actor._initial_behaviour def run(self): """ Main code executed by the actor """ self._setup() while self.state.alive: self.behaviour(self) self._kill_process() def _signal_handler_setup(self): """ Define how to handle signal interrupts """ def term_handler(_, __): self.logger.debug("Term handler") pp_handler = self.state.get_corresponding_handler(PoisonPillMessage()) pp_handler.handle(PoisonPillMessage(soft=False)) self._kill_process() sys.exit(0) signal.signal(signal.SIGTERM, term_handler) signal.signal(signal.SIGINT, term_handler) def _setup(self): """ Set actor specific configuration: - set the processus name - setup the socket interface - setup the signal handler This method is called before entering on the behaviour loop """ # Name process setproctitle.setproctitle(self.name) self.socket_interface.setup() self.logger.debug(self.name + ' process created.') self._signal_handler_setup() self.setup() def setup(self): """ Function called before entering on the behaviour loop Can be overriden to use personal actor setup """ def add_handler(self, message_type, handler): """ Map a handler to a message type :param type message_type: type of the message that the handler can handle :param handler: handler that will handle all messages of the given type :type handler: powerapi.handler.Handler """ self.state.add_handler(message_type, handler) def set_behaviour(self, new_behaviour): """ Set a new behaviour :param new_behaviour: function """ self.behaviour = new_behaviour def _initial_behaviour(self): """ Initial behaviour of an actor Wait for a message, and handle it with the correct handler If the message is None, call the timout_handler otherwise find the handler correponding to the message type and call it on the message. """ msg = self.receive() # Timeout if msg is None: return # Message else: try: handler = self.state.get_corresponding_handler(msg) handler.handle_message(msg) except UnknowMessageTypeException: self.logger.warning("UnknowMessageTypeException: " + str(msg)) except HandlerException: self.logger.warning("HandlerException") def _kill_process(self): """ Kill the actor (close sockets) """ self.socket_interface.close() self.logger.debug(self.name + " teardown") def connect_data(self): """ Open a canal that can be use for unidirectional communication to this actor """ self.socket_interface.connect_data() def connect_control(self): """ Open a control canal with this actor. An actor can have only one control open at the same time. Open a pair socket on the process that want to control this actor """ self.socket_interface.connect_control() def send_control(self, msg): """ Send a message to this actor on the control canal :param Object msg: the message to send to this actor """ self.socket_interface.send_control(msg) self.logger.debug('send control [' + str(msg) + '] to ' + self.name) def receive_control(self, timeout=None): """ Receive a message from this actor on the control canal """ if timeout is None: timeout = self.socket_interface.timeout msg = self.socket_interface.receive_control(timeout) self.logger.debug("receive control : [" + str(msg) + "]") return msg def send_data(self, msg): """ Send a msg to this actor using the data canal :param Object msg: the message to send to this actor """ self.socket_interface.send_data(msg) self.logger.debug('send data [' + str(msg) + '] to ' + self.name) def receive(self): """ Block until a message was received (or until timeout) an return the received messages :return: the list of received messages or an empty list if timeout :rtype: a list of Object """ msg = self.socket_interface.receive() self.logger.debug("receive data : [" + str(msg) + "]") return msg def soft_kill(self): """Kill this actor by sending a soft :class:`PoisonPillMessage <powerapi.message.message.PoisonPillMessage>` """ self.send_control(PoisonPillMessage(soft=True)) self.socket_interface.close() def hard_kill(self): """Kill this actor by sending a hard :class:`PoisonPillMessage <powerapi.message.message.PoisonPillMessage>` """ self.send_control(PoisonPillMessage(soft=False)) self.socket_interface.close()
def __init__(self, name=ACTOR_NAME): Actor.__init__(self, name, level_logger=LOG_LEVEL) self.state = State(Mock(), Mock(), self.logger)
def __init__(self, behaviour, socket_interface, logger, formula_id): State.__init__(self, behaviour, socket_interface, logger) self.formula_id = formula_id