Пример #1
0
def main(argv=tuple(), tbuf=None, **kwargs):
    # instantiate TB
    if tbuf is None:
        from pandaserver.taskbuffer.TaskBuffer import taskBuffer
        taskBuffer.init(panda_config.dbhost,
                        panda_config.dbpasswd,
                        nDBConnection=1)
    else:
        taskBuffer = tbuf
    # dbif session
    session = dbif.get_session()

    # If no argument, call the basic configurator
    if len(argv) == 1:
        _logger = logger_utils.make_logger(base_logger, 'Configurator')
        t1 = time.time()
        configurator = Configurator(session=session)
        if not configurator.run():
            _logger.critical('Configurator loop FAILED')
        t2 = time.time()
        _logger.debug('Configurator run took {0}s'.format(t2 - t1))

    # If --network argument, call the network configurator
    elif len(argv) == 2 and argv[1].lower() == '--network':
        _logger = logger_utils.make_logger(base_logger, 'NetworkConfigurator')
        t1 = time.time()
        network_configurator = NetworkConfigurator(taskBuffer=taskBuffer,
                                                   session=session)
        if not network_configurator.run():
            _logger.critical('Configurator loop FAILED')
        t2 = time.time()
        _logger.debug(' run took {0}s'.format(t2 - t1))

    # If --json_dump
    elif len(argv) == 2 and argv[1].lower() == '--json_dump':
        _logger = logger_utils.make_logger(base_logger, 'JsonDumper')
        t1 = time.time()
        json_dumper = JsonDumper(taskBuffer=taskBuffer, session=session)
        out_msg = json_dumper.run()
        _logger.debug('Json_dumper finished with {0}'.format(out_msg))
        t2 = time.time()
        _logger.debug(' run took {0}s'.format(t2 - t1))
    else:
        _logger.error(
            'Configurator being called with wrong arguments. Use either no arguments or --network or --json_dump'
        )

    # dbif session close
    session.close()
    dbif.engine_dispose()
Пример #2
0
 def _spawn_processors(self, processor_list):
     """
     spawn processors threads
     """
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='_spawn_processors')
     tmp_logger.debug('start')
     for processor_name in processor_list:
         try:
             attr_dict = self.processor_attr_map[processor_name]
             self.processor_thread_map[
                 processor_name] = SimpleMsgProcThread(
                     attr_dict, sleep_time=self.process_sleep_time)
             mc_thread = self.processor_thread_map[processor_name]
             mc_thread.start()
             tmp_logger.info(
                 'spawned processors thread {0} with plugin={1} , in_q={2}, out_q={3}'
                 .format(processor_name,
                         attr_dict['plugin'].__class__.__name__,
                         attr_dict['in_queue'], attr_dict['out_queue']))
         except Exception as e:
             tmp_logger.error(
                 'failed to spawn processor thread {0} with plugin={1} , in_q={2}, out_q={3} ; {4}: {5} '
                 .format(processor_name,
                         attr_dict['plugin'].__class__.__name__,
                         attr_dict['in_queue'], attr_dict['out_queue'],
                         e.__class__.__name__, e))
     tmp_logger.debug('done')
Пример #3
0
 def run(self):
     tmp_log = logger_utils.make_logger(base_logger, method_name='TestingAgent.run')
     while True:
         # do something
         tmp_log.debug('start')
         # sleep
         time.sleep(self.sleepPeriod)
Пример #4
0
 def _kill_processors(self, processor_list, block=True):
     """
     kill processor threads
     """
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='_kill_processors')
     tmp_logger.debug('start')
     for processor_name in processor_list:
         try:
             mc_thread = self.processor_thread_map.get(processor_name)
             if mc_thread is None:
                 tmp_logger.debug(
                     'processor thread {0} does not exist. Skipped...'.
                     format(processor_name))
             elif not mc_thread.is_alive():
                 tmp_logger.debug(
                     'processor thread {0} already stopped. Skipped...'.
                     format(processor_name))
             else:
                 mc_thread.stop()
                 tmp_logger.info(
                     'signaled stop to processor thread {0}, block={1}'.
                     format(processor_name, block))
                 if block:
                     while mc_thread.is_alive():
                         time.sleep(0.125)
                     tmp_logger.info('processor thread {0} stopped'.format(
                         processor_name))
         except Exception as e:
             tmp_logger.error(
                 'failed to stop processor thread {0} ; {1}: {2} '.format(
                     processor_name, e.__class__.__name__, e))
     tmp_logger.debug('done')
Пример #5
0
 def initialize(self):
     """
     customized initialize method
     this method can override attributes set from config file
     """
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='initialize')
     tmp_logger.debug('start')
     pass
     tmp_logger.debug('done')
Пример #6
0
 def process(self, msg_obj, decoded_data=None):
     # logger
     tmp_log = logger_utils.make_logger(base_logger, method_name='process')
     # start
     tmp_log.info('start')
     # parse
     if decoded_data is None:
         # json decode
         try:
             msg_dict = json.loads(msg_obj.data)
         except Exception as e:
             err_str = 'failed to parse message json {2} , skipped. {0} : {1}'.format(e.__class__.__name__, e,
                                                                                      msg_obj.data)
             tmp_log.error(err_str)
             raise
     else:
         msg_dict = decoded_data
     # run
     try:
         tmp_log.debug('got message {0}'.format(msg_dict))
         if msg_dict['msg_type'] == 'generate_job':
             # get task to generate jobs
             jediTaskID = int(msg_dict['taskid'])
             s, taskSpec = self.tbIF.getTaskWithID_JEDI(jediTaskID)
             if not taskSpec:
                 tmp_log.debug('unknown task {}'.format(jediTaskID))
             else:
                 # get WQ
                 vo = taskSpec.vo
                 prodSourceLabel = taskSpec.prodSourceLabel
                 workQueue = self.tbIF.getWorkQueueMap().getQueueWithIDGshare(taskSpec.workQueue_ID, taskSpec.gshare)
                 # get inputs
                 tmpList = self.tbIF.getTasksToBeProcessed_JEDI(self.pid, None, workQueue, None, None, nFiles=1000,
                                                                target_tasks=[jediTaskID])
                 if tmpList:
                     inputList = ListWithLock(tmpList)
                     # create thread
                     threadPool = ThreadPool()
                     siteMapper = self.tbIF.getSiteMapper()
                     taskSetupper = TaskSetupper(vo, prodSourceLabel)
                     taskSetupper.initializeMods(self.tbIF, self.ddmIF)
                     gen = JobGeneratorThread(inputList, threadPool, self.tbIF, self.ddmIF, siteMapper,
                                              True, taskSetupper, self.pid, workQueue, 'pjmsg',
                                              None, None, None, False)
                     gen.start()
                     gen.join()
         else:
             tmp_log.debug('unknown message type : {}'.format(msg_dict['msg_type']))
     except Exception as e:
         err_str = 'failed to run, skipped. {0} : {1}'.format(e.__class__.__name__, e)
         tmp_log.error(err_str)
         raise
     # done
     tmp_log.info('done')
Пример #7
0
def launcher():
    tmp_log = logger_utils.make_logger(base_logger, method_name='launcher')
    tmp_log.debug('start')
    try:
        pass
    except Exception as e:
        # tmp_log.error('failed to read config json file; should not happen... {0}: {1}'.format(e.__class__.__name__, e))
        raise e
    else:
        agent = TestingAgent()
        agent.run()
Пример #8
0
 def _spawn_senders(self, mb_sender_proxy_list):
     """
     spawn connection/listener threads of certain message broker sender proxy
     """
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='_spawn_senders')
     tmp_logger.debug('start')
     for mb_proxy in mb_sender_proxy_list:
         mb_proxy.go()
         tmp_logger.info('spawned listener {0}'.format(mb_proxy.name))
     tmp_logger.debug('done')
Пример #9
0
 def __init__(self, mb_proxy, conn_id, *args, **kwargs):
     # logger
     _token = '{0}-{1}'.format(mb_proxy.__class__.__name__, mb_proxy.name)
     self.logger = logger_utils.make_logger(base_logger,
                                            token=_token,
                                            method_name='MsgListener')
     # associated messgage broker proxy
     self.mb_proxy = mb_proxy
     # connection id
     self.conn_id = conn_id
     # whether log verbosely
     self.verbose = kwargs.get('verbose', False)
Пример #10
0
 def __init__(self, attr_dict, sleep_time):
     GenericThread.__init__(self)
     self.logger = logger_utils.make_logger(
         base_logger,
         token=self.get_pid(),
         method_name='SimpleMsgProcThread')
     self.__to_run = True
     self.plugin = attr_dict['plugin']
     self.in_queue = attr_dict.get('in_queue')
     self.mb_sender_proxy = attr_dict.get('mb_sender_proxy')
     self.sleep_time = sleep_time
     self.verbose = attr_dict.get('verbose', False)
Пример #11
0
 def _parse_config(self):
     """
     parse message processor configuration json file
     Typical example dict from config json:
     mb_servers_dict = {
             'Server_1': {
                 'host_port_list': ['192.168.0.1:777', '192.168.0.2:777'],
                 'use_ssl': True,
                 'cert_file': 'aaa.cert.pem',
                 'key_file': 'bbb.key.pem',
                 'username': '******',
                 'passcode': 'xxxxyyyyzzzz',
                 'vhost': '/somehost',
                 'verbose': True,
             },
             ...
         }
     queues_dict = {
             'Queue_1': {
                 'enable': True,
                 'server': 'Server_1',
                 'destination': '/queue/some_queue',
             },
             ...
         }
     processors_dict = {
             'Processor_1': {
                 'enable': True,
                 'module': 'plugin.module',
                 'name': 'PluginClassName',
                 'in_queue': 'Queue_1',
                 'out_queue': 'Queue_2',
                 'verbose': True,
             },
             ...
         }
     """
     # logger
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='_parse_config')
     tmp_logger.debug('start')
     # parse config json
     with open(self.config_file, 'r') as _f:
         raw_dict = json.load(_f)
     self._mb_servers_dict = raw_dict['mb_servers']
     self._queues_dict = raw_dict['queues']
     self._processors_dict = raw_dict.get('processors', {})
     # set self optional attributes
     if raw_dict.get('guard_period') is not None:
         self.guard_period = raw_dict['guard_period']
     tmp_logger.debug('done')
Пример #12
0
 def _kill_listeners(self, mb_listener_proxy_list):
     """
     kill connection/listener threads of certain message broker listener proxy
     """
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='_kill_listeners')
     tmp_logger.debug('start')
     for mb_proxy in mb_listener_proxy_list:
         mb_proxy.stop()
         tmp_logger.info('signaled stop to listener {0}'.format(
             mb_proxy.name))
     tmp_logger.debug('done')
Пример #13
0
def _get_connection_dict(host_port_list,
                         use_ssl=False,
                         cert_file=None,
                         key_file=None,
                         vhost=None,
                         force=False):
    """
    get dict {conn_id: connection}
    """
    tmp_logger = logger_utils.make_logger(base_logger,
                                          method_name='_get_connection_dict')
    conn_dict = dict()
    # resolve all distinct hosts behind hostname
    resolved_host_port_set = set()
    for host_port in host_port_list:
        host, port = host_port.split(':')
        port = int(port)
        addrinfos = socket.getaddrinfo(host, port)
        for addrinfo in addrinfos:
            resolved_host = socket.getfqdn(addrinfo[4][0])
            resolved_host_port_set.add((resolved_host, port))
    # make connections
    for host, port in resolved_host_port_set:
        host_port = '{0}:{1}'.format(host, port)
        conn_id = host_port
        if conn_id not in conn_dict:
            try:
                conn = stomp.Connection12(host_and_ports=[(host, port)],
                                          vhost=vhost)
                if use_ssl:
                    ssl_opts = {
                        'ssl_version': ssl.PROTOCOL_TLSv1,
                        'cert_file': cert_file,
                        'key_file': key_file
                    }
                    conn.set_ssl(for_hosts=[(host, port)], **ssl_opts)
            except AttributeError:
                # Older version of stomp.py
                ssl_opts = {
                    'use_ssl': use_ssl,
                    'ssl_version': ssl.PROTOCOL_TLSv1,
                    'ssl_cert_file': cert_file,
                    'ssl_key_file': key_file
                }
                conn = stomp.Connection12(host_and_ports=[(host, port)],
                                          vhost=vhost,
                                          **ssl_opts)
            conn_dict[conn_id] = conn
    tmp_logger.debug('got {0} connections to {1}'.format(
        len(conn_dict), ' , '.join(conn_dict.keys())))
    return conn_dict
Пример #14
0
 def __init__(self,
              name,
              host_port_list,
              destination,
              use_ssl=False,
              cert_file=None,
              key_file=None,
              vhost=None,
              username=None,
              passcode=None,
              wait=True,
              verbose=False,
              **kwargs):
     # logger
     self.logger = logger_utils.make_logger(base_logger,
                                            token=name,
                                            method_name='MBSenderProxy')
     # name of message queue
     self.name = name
     # connection parameters
     self.host_port_list = host_port_list
     self.use_ssl = use_ssl
     self.cert_file = cert_file
     self.key_file = key_file
     self.vhost = vhost
     # destination queue to subscribe
     self.destination = destination
     # subscription ID
     self.sub_id = 'panda-MBSenderProxy_{0}_r{1:06}'.format(
         socket.getfqdn(), random.randrange(10**6))
     # client ID
     self.client_id = 'client_{0}_{1}'.format(self.sub_id, hex(id(self)))
     # connect parameters
     self.connect_params = {
         'username': username,
         'passcode': passcode,
         'wait': wait,
         'headers': {
             'client-id': self.client_id
         }
     }
     # number of attempts to restart
     self.n_restart = 0
     # whether got disconnected from on_disconnected
     self.got_disconnected = False
     # whether to disconnect intentionally
     self.to_disconnect = False
     # whether to log verbosely
     self.verbose = verbose
     # get connection
     self._get_connection()
Пример #15
0
 def stop(self, block=True):
     """
     send stop signal to this thread
     """
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='stop')
     tmp_logger.debug('start')
     self.__to_run = False
     tmp_logger.info('signaled stop')
     if block:
         while self.is_alive():
             time.sleep(0.01)
     tmp_logger.debug('done')
 def process(self, msg_obj):
     # logger
     tmp_log = logger_utils.make_logger(base_logger, method_name='process')
     # start
     # tmp_log.info('start')
     # tmp_log.debug('sub_id={0} ; msg_id={1}'.format(msg_obj.sub_id, msg_obj.msg_id))
     # parse yaml
     try:
         message_dict = yaml.safe_load(msg_obj.data)
     except Exception as e:
         err_str = 'failed to parse message yaml {2} , skipped. {0} : {1}'.format(e.__class__.__name__, e, msg_obj.data)
         tmp_log.error(err_str)
         raise
     # run
     try:
         to_continue = True
         dsn = 'UNKNOWN'
         # check event type
         event_type = message_dict['event_type']
         if event_type not in ['datasetlock_ok']:
             # tmp_log.debug('{0} skip'.format(event_type))
             to_continue = False
         if to_continue:
             # tmp_log.debug('{0} start'.format(event_type))
             message_payload = message_dict['payload']
             # only for _dis or _sub
             dsn = message_payload['name']
             if (re.search('_dis\d+$', dsn) is None) and (re.search('_sub\d+$', dsn) is None):
                 # tmp_log.debug('{0} is not _dis or _sub dataset, skip'.format(dsn))
                 to_continue = False
         if to_continue:
             tmp_log.debug('sub_id={0} ; msg_id={1}'.format(msg_obj.sub_id, msg_obj.msg_id))
             tmp_log.debug('{0} start'.format(event_type))
             # take action
             scope = message_payload['scope']
             site  = message_payload['rse']
             tmp_log.debug('{dsn} site={site} type={type}'.format(dsn=dsn, site=site, type=event_type))
             thr = DDMHandler(taskBuffer=self.tbIF, vuid=None, site=site, dataset=dsn, scope=scope)
             # just call run rather than start+join, to run it in main thread instead of spawning new thread
             thr.run()
             del thr
             tmp_log.debug('done {0}'.format(dsn))
     except Exception as e:
         err_str = 'failed to run, skipped. {0} : {1}'.format(e.__class__.__name__, e)
         tmp_log.error(err_str)
         raise
 def process(self, msg_obj):
     # logger
     tmp_log = logger_utils.make_logger(base_logger, method_name='process')
     # start
     # tmp_log.info('start')
     # tmp_log.debug('sub_id={0} ; msg_id={1}'.format(msg_obj.sub_id, msg_obj.msg_id))
     # run
     try:
         msg = msg_obj.data
         tmp_log.debug('forward message {0}'.format(msg))
     except Exception as e:
         err_str = 'failed to run, skipped. {0} : {1}'.format(
             e.__class__.__name__, e)
         tmp_log.error(err_str)
         raise
     # done
     # tmp_log.info('done')
     return msg
Пример #18
0
 def process(self, msg_obj):
     # logger
     tmp_log = logger_utils.make_logger(base_logger, method_name='process')
     # start
     tmp_log.info('start')
     tmp_log.debug('sub_id={0} ; msg_id={1}'.format(msg_obj.sub_id,
                                                    msg_obj.msg_id))
     # parse json
     try:
         msg_dict = json.loads(msg_obj.data)
     except Exception as e:
         err_str = 'failed to parse message json {2} , skipped. {0} : {1}'.format(
             e.__class__.__name__, e, msg_obj.data)
         tmp_log.error(err_str)
         raise
     # sanity check
     try:
         msg_type = msg_dict['msg_type']
     except Exception as e:
         err_str = 'failed to parse message object dict {2} , skipped. {0} : {1}'.format(
             e.__class__.__name__, e, msg_dict)
         tmp_log.error(err_str)
         raise
     # run different plugins according to message type
     try:
         if msg_type in ('file_stagein', 'collection_stagein',
                         'work_stagein'):
             self.plugin_TapeCarousel.process(msg_obj,
                                              decoded_data=msg_dict)
         elif msg_type in ('file_hyperparameteropt',
                           'collection_hyperparameteropt',
                           'work_hyperparameteropt'):
             self.plugin_HPO.process(msg_obj, decoded_data=msg_dict)
         elif msg_type in ('file_processing', 'collection_processing',
                           'work_processing'):
             self.plugin_Processing.process(msg_obj, decoded_data=msg_dict)
         else:
             # Asked by iDDS and message broker guys, JEDI needs to consume unknown types of messages and do nothing...
             warn_str = 'unknown msg_type : {0}'.format(msg_type)
             tmp_log.warning(warn_str)
     except Exception:
         raise
     # done
     tmp_log.info('done')
Пример #19
0
 def _guard_senders(self, mb_sender_proxy_list):
     """
     guard connection/listener threads of certain message broker sender proxy, reconnect when disconnected
     """
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='_guard_senders')
     tmp_logger.debug('start')
     for mb_proxy in mb_sender_proxy_list:
         if mb_proxy.got_disconnected and not mb_proxy.to_disconnect:
             tmp_logger.debug(
                 'found listener {0} disconnected unexpectedly; trigger restart...'
                 .format(mb_proxy.name))
             mb_proxy.restart()
             if mb_proxy.n_restart > 10:
                 tmp_logger.warning(
                     'found listener {0} keep getting disconnected; already restarted {1} times'
                     .format(mb_proxy.name, mb_proxy.n_restart))
             tmp_logger.info('restarted listener {0}'.format(mb_proxy.name))
     tmp_logger.debug('done')
Пример #20
0
def launcher(stop_event):
    tmp_log = logger_utils.make_logger(msg_processor.base_logger,
                                       method_name='launcher')
    tmp_log.debug('start')
    try:
        config_file = jedi_config.msgprocessor.configFile
    except Exception as e:
        tmp_log.error(
            'failed to read config json file; should not happen... {0}: {1}'.
            format(e.__class__.__name__, e))
        raise e
    # start
    agent = MsgProcAgent(config_file)
    agent.start()
    tmp_log.debug('started')
    # wait for stop event
    stop_event.wait()
    # stop
    tmp_log.debug('stopping')
    agent.stop()
    tmp_log.debug('stopped')
Пример #21
0
 def __init__(self, config_file, process_sleep_time=0.0001, **kwargs):
     GenericThread.__init__(self)
     self.__to_run = True
     self.config_file = config_file
     self.process_sleep_time = process_sleep_time
     self.init_mb_listener_proxy_list = []
     self.init_mb_sender_proxy_list = []
     self.init_processor_list = []
     self.processor_attr_map = dict()
     self.processor_thread_map = dict()
     self.guard_period = 300
     self._last_guard_timestamp = 0
     self.prefetch_count = None
     # log
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='__init__')
     # parse config
     self._parse_config()
     # done
     tmp_logger.info('done')
Пример #22
0
 def get_plugin(self, plugin_conf):
     # logger
     tmpLog = logger_utils.make_logger(base_logger,
                                       method_name='get_plugin')
     # use module + class as key
     moduleName = plugin_conf['module']
     className = plugin_conf['name']
     if moduleName is None or className is None:
         tmpLog.warning(
             'Invalid plugin; either module or name is missing '.format(
                 moduleName))
         return None
     pluginKey = '{0}.{1}'.format(moduleName, className)
     # get class
     with self.__lock:
         if pluginKey not in self.classMap:
             # import module
             tmpLog.debug('importing {0}'.format(moduleName))
             mod = __import__(moduleName)
             for subModuleName in moduleName.split('.')[1:]:
                 mod = getattr(mod, subModuleName)
             # get class
             tmpLog.debug('getting class {0}'.format(className))
             cls = getattr(mod, className)
             # add
             self.classMap[pluginKey] = cls
             tmpLog.debug('loaded class {0}'.format(pluginKey))
         else:
             tmpLog.debug(
                 'class {0} already loaded. Skipped'.format(pluginKey))
     # instantiate
     cls = self.classMap[pluginKey]
     inst = cls()
     for tmpKey, tmpVal in plugin_conf.items():
         if tmpKey in ['module', 'name']:
             continue
         setattr(inst, tmpKey, tmpVal)
     tmpLog.debug('created an instance of {0}'.format(pluginKey))
     # return
     return inst
Пример #23
0
 def gshare_preference(self):
     tmp_log = logger_utils.make_logger(main_logger, 'FetchData')
     try:
         # get share and hs info
         if self.gshare_status is None:
             self.gshare_status = self.tbuf.getGShareStatus()
         # initialize
         gshare_dict = dict()
         # rank and data
         for idx, leaf in enumerate(self.gshare_status):
             rank = idx + 1
             gshare = leaf['name']
             gshare_dict[gshare] = {
                 'rank': rank,
                 'running_hs': leaf['running'],
                 'target_hs': leaf['target'],
             }
             tmp_log.debug('rank={rank}, gshare={gshare}'.format(
                 gshare=gshare, **gshare_dict[gshare]))
         # return
         return gshare_dict
     except Exception:
         tmp_log.error(traceback.format_exc())
Пример #24
0
 def run(self):
     """
     main thread
     """
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='run')
     tmp_logger.debug('start')
     # set up instances from config
     self._setup_instances()
     # initialize
     self.initialize()
     # spawn all message broker listener proxy threads
     self._spawn_listeners(self.init_mb_listener_proxy_list)
     # spawn all message broker sender proxy threads
     self._spawn_senders(self.init_mb_sender_proxy_list)
     # spawn all processor threads according to config
     self._spawn_processors(self.init_processor_list)
     # main loop
     tmp_logger.debug('looping')
     while self.__to_run:
         # guard listeners and senders
         if time.time() >= self._last_guard_timestamp + self.guard_period:
             self._guard_listeners(self.init_mb_listener_proxy_list)
             self._guard_senders(self.init_mb_sender_proxy_list)
             self._last_guard_timestamp = time.time()
         # sleep
         time.sleep(0.01)
     # tear down
     tmp_logger.debug('tearing down')
     # kill all message broker listener proxy threads
     self._kill_listeners(self.init_mb_listener_proxy_list)
     # kill all message broker sender proxy threads
     self._kill_senders(self.init_mb_sender_proxy_list)
     # kill all processor threads according to config
     self._kill_processors(self.init_processor_list)
     tmp_logger.debug('done')
Пример #25
0
def launcher(taskBufferIF, ddmIF):
    tmp_log = logger_utils.make_logger(base_logger, method_name='launcher')
    tmp_log.debug('start')
    try:
        jedi_config.daemon.config
    except Exception as e:
        tmp_log.error(
            'failed to read config json file; should not happen... {0}: {1}'.
            format(e.__class__.__name__, e))
        raise e
    # whether to run daemons
    if not getattr(jedi_config.daemon, 'enable', False):
        tmp_log.debug('daemon disabled ; skipped')
        return
    # parameters
    n_workers = getattr(jedi_config.daemon, 'n_proc', 1)
    worker_lifetime = getattr(jedi_config.daemon, 'proc_lifetime', 28800)
    # start
    agent = DaemonMaster(logger=tmp_log,
                         n_workers=n_workers,
                         worker_lifetime=worker_lifetime,
                         tbuf=taskBufferIF,
                         ddmif=ddmIF)
    agent.run()
Пример #26
0
 def start_passive_mode(self,
                        in_q_list=None,
                        out_q_list=None,
                        prefetch_size=100):
     """
     start passive mode: only spwan mb proxies (without spawning agent and plugin threads)
     in_q_list: list of inward queue name
     out_q_list: list of outward queue name
     prefetch_size: prefetch size of the message broker (can control number of un-acknowledged messages stored in the local buffer)
     returns dict of mb proxies
     """
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='start_passive_mode')
     tmp_logger.debug('start')
     # initialize
     # self.initialize()
     all_queue_names = list(self._queues_dict.keys())
     if in_q_list is None:
         in_q_list = all_queue_names
     if out_q_list is None:
         out_q_list = all_queue_names
     # mb_listener_proxy instances
     mb_listener_proxy_dict = dict()
     for in_queue in in_q_list:
         if in_queue not in self._queues_dict:
             continue
         qconf = self._queues_dict[in_queue]
         if not qconf.get('enable', True):
             continue
         sconf = self._mb_servers_dict[qconf['server']]
         mb_listener_proxy = get_mb_proxy(name=in_queue,
                                          sconf=sconf,
                                          qconf=qconf,
                                          mode='listener',
                                          prefetch_size=prefetch_size)
         mb_listener_proxy_dict[in_queue] = mb_listener_proxy
     # mb_sender_proxy instances
     mb_sender_proxy_dict = dict()
     for out_queue in out_q_list:
         if out_queue not in self._queues_dict:
             continue
         qconf = self._queues_dict[out_queue]
         if not qconf.get('enable', True):
             continue
         sconf = self._mb_servers_dict[qconf['server']]
         mb_sender_proxy = get_mb_proxy(name=out_queue,
                                        sconf=sconf,
                                        qconf=qconf,
                                        mode='sender')
         mb_sender_proxy_dict[out_queue] = mb_sender_proxy
     # spawn message broker listener proxy connections
     for queue_name, mb_proxy in mb_listener_proxy_dict.items():
         mb_proxy.go()
         tmp_logger.debug(
             'spawned listener proxy for {0}'.format(queue_name))
     # spawn message broker sender proxy connections
     for queue_name, mb_proxy in mb_sender_proxy_dict.items():
         mb_proxy.go()
         tmp_logger.debug('spawned sender proxy for {0}'.format(queue_name))
     tmp_logger.debug('done')
     # return
     return {
         'in': mb_listener_proxy_dict,
         'out': mb_sender_proxy_dict,
     }
Пример #27
0
 def __init__(self,
              name,
              host_port_list,
              destination,
              use_ssl=False,
              cert_file=None,
              key_file=None,
              vhost=None,
              username=None,
              passcode=None,
              wait=True,
              ack_mode='client-individual',
              skip_buffer=False,
              conn_mode='all',
              prefetch_size=None,
              verbose=False,
              **kwargs):
     # logger
     self.logger = logger_utils.make_logger(base_logger,
                                            token=name,
                                            method_name='MBListenerProxy')
     # name of message queue
     self.name = name
     # connection parameters
     self.host_port_list = host_port_list
     self.use_ssl = use_ssl
     self.cert_file = cert_file
     self.key_file = key_file
     self.vhost = vhost
     # destination queue to subscribe
     self.destination = destination
     # subscription ID
     self.sub_id = 'panda-MBListenerProxy_{0}_r{1:06}'.format(
         socket.getfqdn(), random.randrange(10**6))
     # client ID
     self.client_id = 'client_{0}_{1}'.format(self.sub_id, hex(id(self)))
     # connect parameters
     self.connect_params = {
         'username': username,
         'passcode': passcode,
         'wait': wait,
         'headers': {
             'client-id': self.client_id
         }
     }
     # acknowledge mode
     self.ack_mode = ack_mode
     # associate message buffer
     self.msg_buffer = MsgBuffer(queue_name=self.name)
     # connection mode; "all" or "any"
     self.conn_mode = conn_mode
     # connection dict
     self.connection_dict = {}
     # message listener dict
     self.listener_dict = {}
     # whether to skip buffer and dump to self.dump_msgs; True only in testing
     self.skip_buffer = skip_buffer
     # dump messages
     self.dump_msgs = []
     # number of attempts to restart
     self.n_restart = 0
     # whether got disconnected from on_disconnected
     self.got_disconnected = False
     # whether to disconnect intentionally
     self.to_disconnect = False
     # whether to log verbosely
     self.verbose = verbose
     # prefetch count of the MB (max number of un-acknowledge messages allowed)
     self.prefetch_size = prefetch_size
     # evaluate subscription headers
     self._evaluate_subscription_headers()
     # get connections
     self._get_connections()
Пример #28
0
 def run(self):
     # update logger thread id
     self.logger = logger_utils.make_logger(
         base_logger,
         token=self.get_pid(),
         method_name='SimpleMsgProcThread')
     # start
     self.logger.info('start run')
     # initialization step of plugin
     self.logger.info('plugin initialize')
     self.plugin.initialize()
     # message buffer
     self.logger.info('message buffer is {0}'.format(self.in_queue))
     msg_buffer = MsgBuffer(queue_name=self.in_queue)
     # main loop
     self.logger.info('start loop')
     while self.__to_run:
         is_processed = False
         proc_ret = None
         # as consumer
         if self.in_queue:
             # get from buffer
             msg_obj = msg_buffer.get()
             if msg_obj is not None:
                 if self.verbose:
                     self.logger.debug('received a new message')
                     self.logger.debug('plugin process start')
                 try:
                     with msg_obj as _msg_obj:
                         proc_ret = self.plugin.process(_msg_obj)
                     is_processed = True
                     if self.verbose:
                         self.logger.debug('successfully processed')
                 except Exception as e:
                     self.logger.error(
                         'error when process message msg_id={0} with {1}: {2} '
                         .format(msg_obj.msg_id, e.__class__.__name__, e))
                 if self.verbose:
                     self.logger.debug('plugin process end')
         else:
             if self.verbose:
                 self.logger.debug('plugin process start')
             try:
                 proc_ret = self.plugin.process(None)
                 is_processed = True
                 if self.verbose:
                     self.logger.debug('successfully processed')
             except Exception as e:
                 self.logger.error(
                     'error when process with {0}: {1} '.format(
                         msg_obj.msg_id, e.__class__.__name__, e))
             if self.verbose:
                 self.logger.debug('plugin process end')
         # as producer
         if self.mb_sender_proxy and is_processed:
             self.mb_sender_proxy.send(proc_ret)
             if self.verbose:
                 self.logger.debug('sent a processed message')
         # sleep
         time.sleep(self.sleep_time)
     # stop loop
     self.logger.info('stopped loop')
     # tear down
     self.logger.info('stopped run')
Пример #29
0
 def process(self, msg_obj, decoded_data=None):
     # logger
     tmp_log = logger_utils.make_logger(base_logger, method_name='process')
     # start
     tmp_log.info('start')
     tmp_log.debug('sub_id={0} ; msg_id={1}'.format(msg_obj.sub_id,
                                                    msg_obj.msg_id))
     # parse
     if decoded_data is None:
         # json decode
         try:
             msg_dict = json.loads(msg_obj.data)
         except Exception as e:
             err_str = 'failed to parse message json {2} , skipped. {0} : {1}'.format(
                 e.__class__.__name__, e, msg_obj.data)
             tmp_log.error(err_str)
             raise
     else:
         msg_dict = decoded_data
     # sanity check
     try:
         jeditaskid = int(msg_dict['workload_id'])
         # message type
         msg_type = msg_dict['msg_type']
         if msg_type == 'file_processing':
             target_list = msg_dict['files']
         elif msg_type == 'collection_processing':
             target_list = msg_dict['collections']
         elif msg_type == 'work_processing':
             pass
         else:
             raise ValueError(
                 'invalid msg_type value: {0}'.format(msg_type))
         # relation type
         relation_type = msg_dict.get('relation_type')
     except Exception as e:
         err_str = 'failed to parse message object dict {2} , skipped. {0} : {1}'.format(
             e.__class__.__name__, e, msg_dict)
         tmp_log.error(err_str)
         raise
     # run
     try:
         # initialize to_proceed
         to_proceed = False
         # type filters
         if msg_type in ['file_processing', 'collection_processing'] \
                 and relation_type in ['input']:
             to_proceed = True
         # whether to proceed the targets
         if to_proceed:
             # initialize
             scope_name_list_map = {}
             missing_files_list = []
             # loop over targets
             for target in target_list:
                 name = target['name']
                 scope = target['scope']
                 if (msg_type == 'file_processing' and target['status'] in ['Available']) \
                         or (msg_type == 'collection_processing' and target['status'] in ['Closed']):
                     scope_name_list_map.setdefault(scope, [])
                     scope_name_list_map[scope].append(name)
                 elif (msg_type == 'file_processing'
                       and target['status'] in ['Missing']):
                     # missing files
                     missing_files_list.append(name)
                 else:
                     # got target in bad attributes, do nothing
                     tmp_log.debug(
                         'jeditaskid={jeditaskid}, scope={scope}, msg_type={msg_type}, status={status}, did nothing for bad target'
                         .format(jeditaskid=jeditaskid,
                                 scope=scope,
                                 msg_type=msg_type,
                                 status=target['status']))
                     pass
             # run by each scope
             for scope, name_list in scope_name_list_map.items():
                 # about files or datasets in good status
                 if msg_type == 'file_processing':
                     tmp_log.debug(
                         'jeditaskid={0}, scope={1}, update about files...'.
                         format(jeditaskid, scope))
                     res = self.tbIF.updateInputFilesStagedAboutIdds_JEDI(
                         jeditaskid, scope, name_list)
                     if res is None:
                         # got error and rollback in dbproxy
                         err_str = 'jeditaskid={0}, scope={1}, failed to update files'.format(
                             jeditaskid, scope)
                         raise RuntimeError(err_str)
                     tmp_log.info(
                         'jeditaskid={0}, scope={1}, updated {2} files'.
                         format(jeditaskid, scope, res))
                 elif msg_type == 'collection_processing':
                     tmp_log.debug(
                         'jeditaskid={0}, scope={1}, update about datasets...'
                         .format(jeditaskid, scope))
                     res = self.tbIF.updateInputDatasetsStagedAboutIdds_JEDI(
                         jeditaskid, scope, name_list)
                     if res is None:
                         # got error and rollback in dbproxy
                         err_str = 'jeditaskid={0}, scope={1}, failed to update datasets'.format(
                             jeditaskid, scope)
                         raise RuntimeError(err_str)
                     tmp_log.info(
                         'jeditaskid={0}, scope={1}, updated {2} datasets'.
                         format(jeditaskid, scope, res))
                 # check if all ok
                 if res == len(target_list):
                     tmp_log.debug(
                         'jeditaskid={0}, scope={1}, all OK'.format(
                             jeditaskid, scope))
                 elif res < len(target_list):
                     tmp_log.warning(
                         'jeditaskid={0}, scope={1}, only {2} out of {3} done...'
                         .format(jeditaskid, scope, res, len(target_list)))
                 elif res > len(target_list):
                     tmp_log.warning(
                         'jeditaskid={0}, scope={1}, strangely, {2} out of {3} done...'
                         .format(jeditaskid, scope, res, len(target_list)))
                 else:
                     tmp_log.warning(
                         'jeditaskid={0}, scope={1}, something unwanted happened...'
                         .format(jeditaskid, scope))
             # handle missing files
             n_missing = len(missing_files_list)
             if n_missing > 0:
                 res = self.tbIF.setMissingFilesAboutIdds_JEDI(
                     jeditaskid=jeditaskid, filenames=missing_files_list)
                 if res == n_missing:
                     tmp_log.debug(
                         'jeditaskid={0}, marked all {1} files missing'.
                         format(jeditaskid, n_missing))
                 elif res < n_missing:
                     tmp_log.warning(
                         'jeditaskid={0}, only {1} out of {2} files marked missing...'
                         .format(jeditaskid, res, n_missing))
                 elif res > n_missing:
                     tmp_log.warning(
                         'jeditaskid={0}, strangely, {1} out of {2} files marked missing...'
                         .format(jeditaskid, res, n_missing))
                 else:
                     tmp_log.warning(
                         'jeditaskid={0}, res={1}, something unwanted happened about missing files...'
                         .format(jeditaskid, res))
         else:
             # do nothing
             tmp_log.debug(
                 'jeditaskid={jeditaskid}, msg_type={msg_type}, relation_type={relation_type}, nothing done'
                 .format(jeditaskid=jeditaskid,
                         msg_type=msg_type,
                         relation_type=relation_type))
     except Exception as e:
         err_str = 'failed to process the message, skipped. {0} : {1}'.format(
             e.__class__.__name__, e)
         tmp_log.error(err_str)
         raise
     # done
     tmp_log.info('done')
Пример #30
0
 def _setup_instances(self):
     """
     set up attributes and MBListenerProxy/plugin instances accordingly
     """
     # logger
     tmp_logger = logger_utils.make_logger(base_logger,
                                           token=self.get_pid(),
                                           method_name='_setup_instances')
     tmp_logger.debug('start')
     # processor thread attribute dict
     processor_attr_map = dict()
     # inward/outward queues and plugin instances
     in_q_set = set()
     out_q_set = set()
     for proc, pconf in self._processors_dict.items():
         # skip if not enabled
         if not pconf.get('enable', True):
             continue
         # queues
         in_queue = pconf.get('in_queue')
         out_queue = pconf.get('out_queue')
         if in_queue:
             in_q_set.add(in_queue)
         if out_queue:
             out_q_set.add(out_queue)
         # plugin
         plugin_factory = PluginFactory()
         plugin = plugin_factory.get_plugin(pconf)
         # fill in thread attribute dict
         processor_attr_map[proc] = dict()
         processor_attr_map[proc]['in_queue'] = in_queue
         processor_attr_map[proc]['out_queue'] = out_queue
         processor_attr_map[proc]['plugin'] = plugin
     # mb_listener_proxy instances
     mb_listener_proxy_dict = dict()
     for in_queue in in_q_set:
         qconf = self._queues_dict[in_queue]
         if not qconf.get('enable', True):
             continue
         sconf = self._mb_servers_dict[qconf['server']]
         mb_listener_proxy = get_mb_proxy(name=in_queue,
                                          sconf=sconf,
                                          qconf=qconf,
                                          mode='listener')
         mb_listener_proxy_dict[in_queue] = mb_listener_proxy
     # mb_sender_proxy instances
     mb_sender_proxy_dict = dict()
     for out_queue in out_q_set:
         qconf = self._queues_dict[out_queue]
         if not qconf.get('enable', True):
             continue
         sconf = self._mb_servers_dict[qconf['server']]
         mb_sender_proxy = get_mb_proxy(name=out_queue,
                                        sconf=sconf,
                                        qconf=qconf,
                                        mode='sender')
         mb_sender_proxy_dict[out_queue] = mb_sender_proxy
     # keep filling in thread attribute dict
     for proc in processor_attr_map.keys():
         in_queue = processor_attr_map[proc]['in_queue']
         if in_queue:
             processor_attr_map[proc][
                 'mb_listener_proxy'] = mb_listener_proxy_dict[in_queue]
         out_queue = processor_attr_map[proc]['out_queue']
         if out_queue:
             processor_attr_map[proc][
                 'mb_sender_proxy'] = mb_sender_proxy_dict[out_queue]
     # set self attributes
     self.init_processor_list = list(processor_attr_map.keys())
     self.init_mb_listener_proxy_list = list(
         mb_listener_proxy_dict.values())
     self.init_mb_sender_proxy_list = list(mb_sender_proxy_dict.values())
     self.processor_attr_map = dict(processor_attr_map)
     # tear down
     del in_q_set, out_q_set, mb_listener_proxy_dict, mb_sender_proxy_dict, processor_attr_map
     tmp_logger.debug('done')