def supervisor(request): """ return a supervisor """ supervisor = Supervisor() supervisor.actor_list = request.param yield supervisor
def test_no_stream(self): """ Test if the actor kill himself after reading db """ puller = PullerActor("puller_mongo", get_fake_db(), get_fake_filter(), 0) supervisor = Supervisor() supervisor.launch_actor(puller) puller.join() assert puller.is_alive() is False
def initialized_dispatcher(dispatcher): """ Return a DispatcherActor, start it, connect its sockets and send it a StartMessage teardown : terminate the Dispatcher process and close open sockets """ supervisor = Supervisor() supervisor.launch_actor(dispatcher) yield dispatcher dispatcher.terminate() dispatcher.join() dispatcher.socket_interface.close()
def __init__(self, behaviour, socket_interface, logger): """ :param behaviour: function that implement the basic behaviour :type behaviour: (fun (actor) -> None) :param socket_interface: communication interface of the actor :type socket_interface: powerapi.actor.socket_interface.SocketInterface """ #: (bool): True if the actor is initialized and can handle all #: message, False otherwise self.initialized = False #: (bool): True if the actor is alive, False otherwise self.alive = True #: (powerapi.SocketInterface): Communication interface of the actor self.socket_interface = socket_interface #: (func): Function that implement the current behaviour self.behaviour = behaviour #: ([(type, powerapi.handler.abstract_handler.AbstractHandler)]): #: mapping between message type and handler that the mapped handler #: must handle self.handlers = [] #: (func): function activated when no message was #: received since `timeout` milliseconds self.timeout_handler = TimeoutHandler() #: (powerapi.actor.supervisor.Supervisor): object that supervise actors #: that are handle by this actor self.supervisor = Supervisor() #: (logging.Logger): Logger self.logger = logger
def test_create_dispatcher_without_primary(dispatcher2): """ Create a Dispatcher with no primary dispatch rule Test if the actor actor initialisation raise an ActorInitError """ with pytest.raises(CrashConfigureError): Supervisor().launch_actor(dispatcher2)
def test_create_double_dispatcher(initialized_dispatcher, dispatcher3): """ Create two dispatcher with different names Test : - if the two dispatcher are alive """ Supervisor().launch_actor(dispatcher3) assert is_actor_alive(dispatcher3) assert is_actor_alive(initialized_dispatcher)
def test_kill_actor_right_method(): """ create a supervisor that supervise one actor. Use the test the kill_actors method Test if: - the hard_kill method of the supervised actor was used """ supervisor = Supervisor() actor = FakeActor() actor.hard_kill = Mock() actor.soft_kill = Mock() actor.alive = True supervisor.supervised_actors = [actor] supervisor.kill_actors() assert actor.hard_kill.call_count == 1 assert not actor.soft_kill.called
def __init__(self, actor): """ :param powerapi.Actor actor: Actor """ #: (bool): True if the actor is initialized and can handle all #: message, False otherwise self.initialized = False #: (bool): True if the actor is alive, False otherwise self.alive = True #: ([(type, powerapi.handler.abstract_handler.AbstractHandler)]): #: mapping between message type and handler that the mapped handler #: must handle self.handlers = [] #: (powerapi.actor.supervisor.Supervisor): object that supervise actors #: that are handle by this actor self.supervisor = Supervisor() #: (powerapi.Actor): Actor self.actor = actor
def test_create_formula_double_dispatcher(initialized_dispatcher, dispatcher3, formula_socket): """ Create two dispatcher with different names but same dispatch rules and send them the same HWPCReport Test: - if each dispatcher are alive - if each dispatcher create one formula """ Supervisor().launch_actor(dispatcher3) initialized_dispatcher.send_data(gen_good_report()) assert is_actor_alive(initialized_dispatcher) assert receive(formula_socket) == gen_good_report() assert receive(formula_socket) is None dispatcher3.send_data(gen_good_report()) assert is_actor_alive(dispatcher3) assert receive(formula_socket) == gen_good_report() assert receive(formula_socket) is None
def __init__(self, actor): """ :param powerapi.Actor actor: Actor """ #: (bool): True if the actor is initialized and can handle all #: message, False otherwise self.initialized = False #: (bool): True if the actor is alive, False otherwise self.alive = True #: ([(type, powerapi.handler.abstract_handler.AbstractHandler)]): #: mapping between message type and handler that the mapped handler #: must handle self.handlers = [] #: (func): function activated when no message was #: received since `timeout` milliseconds self.timeout_handler = TimeoutHandler(self) #: (powerapi.actor.supervisor.Supervisor): object that supervise actors #: that are handle by this actor self.supervisor = Supervisor() #: (powerapi.Actor): Actor self.actor = actor
def run_smartwatts(args, logger): """ Run PowerAPI with the SmartWatts formula. :param args: CLI arguments namespace :param logger: Log level to use for the actors """ # Print configuration logger.info('SmartWatts version %s using PowerAPI version %s', smartwatts_version, powerapi_version) logger.info('CPU formula parameters: RAPL_REF=%s ERROR_THRESHOLD=%sW' % (args.cpu_rapl_ref_event, args.cpu_error_threshold)) logger.info('DRAM formula parameters: RAPL_REF=%s ERROR_THRESHOLD=%sW' % (args.dram_rapl_ref_event, args.dram_error_threshold)) # Reports pusher power_output_mongodb = MongoDB(args.mongodb_uri, args.mongodb_database, args.mongodb_powermeter_collection, None) power_report_pusher = PusherActor('power_report_pusher', PowerReport, power_output_mongodb) formula_output_mongodb = MongoDB(args.mongodb_uri, args.mongodb_database, args.mongodb_formula_collection, None) formula_report_pusher = PusherActor('formula_report_pusher', FormulaReport, formula_output_mongodb) # Sensor reports route table route_table = RouteTable() route_table.dispatch_rule(HWPCReport, HWPCDispatchRule(HWPCDepthLevel.SOCKET, primary=True)) # Shared parameters pushers = {'power': power_report_pusher, 'formula': formula_report_pusher} cpu_topology = CPUTopology(args.cpu_base_clock, args.cpu_ratio_min, args.cpu_ratio_base, args.cpu_ratio_max) # CPU formula dispatcher def cpu_formula_factory(name: str, _): scope = SmartWattsFormulaScope.CPU config = SmartWattsFormulaConfig(scope, args.cpu_rapl_ref_event, args.cpu_error_threshold, cpu_topology) return SmartWattsFormulaActor(name, pushers, config) cpu_dispatcher = DispatcherActor('cpu_dispatcher', cpu_formula_factory, route_table) # DRAM formula dispatcher def dram_formula_factory(name: str, _): scope = SmartWattsFormulaScope.DRAM config = SmartWattsFormulaConfig(scope, args.cpu_rapl_ref_event, args.cpu_error_threshold, cpu_topology) return SmartWattsFormulaActor(name, pushers, config) dram_dispatcher = DispatcherActor('dram_dispatcher', dram_formula_factory, route_table) # Sensor reports puller input_mongodb = MongoDB(args.mongodb_uri, args.mongodb_database, args.mongodb_sensor_collection, HWPCModel(), stream_mode=True) report_filter = Filter() report_filter.filter(lambda msg: True, cpu_dispatcher) report_filter.filter(lambda msg: True, dram_dispatcher) puller = PullerActor('hwpc_report_puller', input_mongodb, report_filter) def term_handler(_, __): puller.join() cpu_dispatcher.join() dram_dispatcher.join() power_report_pusher.join() formula_report_pusher.join() exit(0) # TERM/INT signals handler signal.signal(signal.SIGTERM, term_handler) signal.signal(signal.SIGINT, term_handler) # Actors supervision supervisor = Supervisor() try: supervisor.launch_actor(power_report_pusher) supervisor.launch_actor(formula_report_pusher) supervisor.launch_actor(cpu_dispatcher) supervisor.launch_actor(dram_dispatcher) supervisor.launch_actor(puller) logger.info('Actors initialized, SmartWatts is now running...') except zmq.error.ZMQError as exn: logger.error('Communication error, ZMQError code : ' + str(exn.errno) + ' reason : ' + exn.strerror) supervisor.kill_actors() except ActorInitError as exn: logger.error('Actor initialisation error, reason : ' + exn.message) supervisor.kill_actors() supervisor.join()