Esempio n. 1
0
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")
Esempio n. 2
0
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}")
Esempio n. 3
0
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()