Example #1
0
    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)
Example #2
0
    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
Example #3
0
    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 = []
Example #4
0
    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
Example #5
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
Example #6
0
 def __init__(self):
     Actor.__init__(self, 'test_supervisor')
     self.state = State(Mock())
     self.send_msg = []
     self.alive = False
Example #7
0
 def __init__(self):
     Actor.__init__(self, 'test_supervisor')
     self.state = State(Mock(), SocketInterface('test_supervisor', 0),
                        Mock())
     self.send_msg = []
     self.alive = False
Example #8
0
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()
Example #9
0
 def __init__(self, name=ACTOR_NAME):
     Actor.__init__(self, name, level_logger=LOG_LEVEL)
     self.state = State(Mock(), Mock(), self.logger)
Example #10
0
 def __init__(self, behaviour, socket_interface, logger, formula_id):
     State.__init__(self, behaviour, socket_interface, logger)
     self.formula_id = formula_id