def start_endpoint(args, global_config=None): """Start an endpoint This function will do: 1. Connect to the broker service, and register itself 2. Get connection info from broker service 3. Start the interchange as a daemon | Broker service | | -----2----> Forwarder | | /register <-----3----+ ^ | +-----^-----------------------+-------------+ | | | 1 4 6 | v | +-----+-----+-----+ v | Start |---5---> Interchange | Endpoint | daemon +-----------------+ Parameters ---------- args : args object Args object from the arg parsing endpoint_uuid : str Endpoint UUID string to register with global_config : dict Global config dict """ endpoint_dir = os.path.join(args.config_dir, args.name) endpoint_json = os.path.join(endpoint_dir, 'endpoint.json') if not os.path.exists(endpoint_dir): print('''Endpoint {0} is not configured! 1. Please create a configuration template with: $ funcx-endpoint configure {0} 2. Update configuration 3. Start the endpoint. '''.format(args.name)) return # If pervious registration info exists, use that if os.path.exists(endpoint_json): with open(endpoint_json, 'r') as fp: logger.debug( "Connection info loaded from prior registration record") reg_info = json.load(fp) else: logger.debug( "Endpoint prior connection record not available. Attempting registration" ) if global_config.get('broker_test', False) is True: logger.warning( "**************** BROKER DEBUG MODE *******************") reg_info = register_with_hub(global_config['broker_address'], global_config['redis_host']) else: funcx_client = FuncXClient() logger.debug("Attempting registration") endpoint_uuid = str(uuid.uuid4()) if args.endpoint_uuid: endpoint_uuid = args.endpoint_uuid logger.debug(f"Trying with eid : {endpoint_uuid}") reg_info = funcx_client.register_endpoint(args.name, endpoint_uuid) logger.info("Endpoint registered with UUID: {}".format( reg_info['endpoint_id'])) with open(os.path.join(endpoint_dir, 'endpoint.json'), 'w+') as fp: json.dump(reg_info, fp) logger.debug( "Registration info written to {}/endpoint.json".format( endpoint_dir)) optionals = {} optionals['client_address'] = reg_info['address'] optionals['client_ports'] = reg_info['client_ports'].split(',') if 'endpoint_address' in global_config: optionals['interchange_address'] = global_config['endpoint_address'] optionals['logdir'] = endpoint_dir # optionals['debug'] = True if args.debug: optionals['logging_level'] = logging.DEBUG import importlib.machinery endpoint_config = importlib.machinery.SourceFileLoader( 'config', os.path.join(endpoint_dir, 'config.py')).load_module() # TODO : we need to load the config ? maybe not. This needs testing stdout = open(os.path.join(endpoint_dir, './interchange.stdout'), 'w+') stderr = open(os.path.join(endpoint_dir, './interchange.stderr'), 'w+') try: context = daemon.DaemonContext( working_directory=endpoint_dir, umask=0o002, # lockfile.FileLock( pidfile=daemon.pidfile.PIDLockFile( os.path.join(endpoint_dir, 'daemon.pid')), stdout=stdout, stderr=stderr, ) except Exception as e: print("Caught exception while trying to setup endpoint context dirs") print("Exception : ", e) check_pidfile(context.pidfile.path, "funcx-endpoint", args.name) with context: ic = Interchange(endpoint_config.config, **optionals) ic.start() stdout.close() stderr.close() print("Done")
def start_endpoint( name: str = typer.Argument("default", autocompletion=complete_endpoint_name), endpoint_uuid: str = typer.Option( None, help="The UUID for the endpoint to register with")): """Start an endpoint This function will do: 1. Connect to the broker service, and register itself 2. Get connection info from broker service 3. Start the interchange as a daemon | Broker service | | -----2----> Forwarder | | /register <-----3----+ ^ | +-----^-----------------------+-------------+ | | | 1 4 6 | v | +-----+-----+-----+ v | Start |---5---> Interchange | Endpoint | daemon +-----------------+ Parameters ---------- name : str endpoint_uuid : str """ endpoint_dir = os.path.join(State.FUNCX_DIR, name) endpoint_json = os.path.join(endpoint_dir, 'endpoint.json') # TODO : we need to load the config ? maybe not. This needs testing endpoint_config = SourceFileLoader( 'config', os.path.join(endpoint_dir, FUNCX_CONFIG_FILE_NAME)).load_module() funcx_client = FuncXClient( funcx_service_address=endpoint_config.config.funcx_service_address) if not os.path.exists(endpoint_dir): print('''Endpoint {0} is not configured! 1. Please create a configuration template with: $ funcx-endpoint configure {0} 2. Update configuration 3. Start the endpoint. '''.format(name)) return # If pervious registration info exists, use that if os.path.exists(endpoint_json): with open(endpoint_json, 'r') as fp: logger.debug( "Connection info loaded from prior registration record") reg_info = json.load(fp) endpoint_uuid = reg_info['endpoint_id'] elif not endpoint_uuid: endpoint_uuid = str(uuid.uuid4()) logger.info(f"Starting endpoint with uuid: {endpoint_uuid}") # Create a daemon context stdout = open(os.path.join(endpoint_dir, './interchange.stdout'), 'w+') stderr = open(os.path.join(endpoint_dir, './interchange.stderr'), 'w+') try: context = daemon.DaemonContext( working_directory=endpoint_dir, umask=0o002, # lockfile.FileLock( pidfile=daemon.pidfile.PIDLockFile( os.path.join(endpoint_dir, 'daemon.pid')), stdout=stdout, stderr=stderr, ) except Exception as e: logger.critical( "Caught exception while trying to setup endpoint context dirs") logger.critical("Exception : ", e) check_pidfile(context.pidfile.path, "funcx-endpoint", name) with context: while True: # Register the endpoint logger.debug("Registering endpoint") if State.FUNCX_CONFIG.get('broker_test', False) is True: logger.warning( "**************** BROKER State.DEBUG MODE *******************" ) reg_info = register_with_hub( endpoint_uuid, endpoint_dir, State.FUNCX_CONFIG['broker_address'], State.FUNCX_CONFIG['redis_host']) else: metadata = None try: metadata = endpoint_config.meta except AttributeError: logger.info("Did not find associated endpoint metadata") reg_info = register_endpoint(funcx_client, name, endpoint_uuid, metadata, endpoint_dir) logger.info("Endpoint registered with UUID: {}".format( reg_info['endpoint_id'])) # Configure the parameters for the interchange optionals = {} optionals['client_address'] = reg_info['address'] optionals['client_ports'] = reg_info['client_ports'].split(',') if 'endpoint_address' in State.FUNCX_CONFIG: optionals['interchange_address'] = State.FUNCX_CONFIG[ 'endpoint_address'] optionals['logdir'] = endpoint_dir if State.DEBUG: optionals['logging_level'] = logging.DEBUG ic = Interchange(endpoint_config.config, endpoint_id=endpoint_uuid, **optionals) ic.start() ic.stop() logger.critical("Interchange terminated.") time.sleep(10) stdout.close() stderr.close() logger.critical(f"Shutting down endpoint {endpoint_uuid}")
import argparse from funcx.config import Config from funcx.executors.high_throughput.interchange import Interchange config = Config() import funcx funcx.set_stream_logger() if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument("-a", "--address", help="Address") parser.add_argument("-c", "--client_ports", help="ports") args = parser.parse_args() ic = Interchange( config, client_address=args.address, client_ports=[int(i) for i in args.client_ports.split(',')], ) ic.start()