예제 #1
0
def start_service(api_class, service_class, log,
                  services=None, host='localhost', port=9100):
    """Start a Data API service.

    Args:
        api_class (BaseService): The custom API service class, e.g.,
                    `doekbase.data_api.taxonomy.taxon.api.TaxonService`
        service_class (type): The Thrift auto-generated service class
        log (logging.Logger): Logging object
        services (dict): Service configuration dictionary, passed to
                         constructor of the `api_class`.
        host (str): Service host (will default to 'localhost')
        port (int): Service port, e.g. 9101
    """
    assert issubclass(api_class, BaseService), \
        'Invalid "api_class": must be a subclass of ' \
        'doekbase.data_api.service_core.BaseService'
    assert hasattr(service_class, 'Processor'), 'Invalid "service_class": ' \
                                                'missing "Processor" attribute'
    assert isinstance(port, int), 'The "port" must be an integer'
    log.debug('method=start_service state=begin host={host} port={port:d}'
               .format(host=host, port=port))

    # Create server
    services = services or SERVICES_DICT
    handler = api_class(services)
    processor = service_class.Processor(handler)
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()
    resource = TTwisted.ThriftResource(processor, pfactory, pfactory)
    site = twisted.web.server.Site(resource=resource)
    twisted.internet.reactor.listenTCP(port, site, interface=host)

    # Run server
    sname = api_class.__name__
    shost = host or 'localhost'
    log.info('msg="Starting {} server at {}:{}"'.format(sname, shost, port))
    log.debug('method=twisted.internet.reactor.run state=begin')
    try:
        twisted.internet.reactor.run()
    except Exception as err:
        log.error('msg="Abort {} server on error"'.format(sname))
        log.error('method=twisted.internet.reactor.run state=error '
                   'error_message={e}'.format(e=err))
        raise
    finally:
        log.debug('method=twisted.internet.reactor.run state=end')
    return 0
예제 #2
0
def start_service(api_class,
                  service_class,
                  log,
                  services=None,
                  host='localhost',
                  port=9100,
                  killprocgrp=False):
    """Start a Data API service.

    Args:
        api_class (BaseService): The custom API service class, e.g.,
                    `doekbase.data_api.taxonomy.taxon.api.TaxonService`
        service_class (type): The Thrift auto-generated service class
        log (logging.Logger): Logging object
        services (dict): Service configuration dictionary, passed to
                         constructor of the `api_class`.
        host (str): Service host (will default to 'localhost')
        port (int): Service port, e.g. 9101
        killprocgrp (bool): if True, kill process group on exit
    """
    assert issubclass(api_class, BaseService), \
        'Invalid "api_class": must be a subclass of ' \
        'doekbase.data_api.service_core.BaseService'
    assert hasattr(service_class, 'Processor'), 'Invalid "service_class": ' \
                                                'missing "Processor" attribute'
    assert isinstance(port, int), 'The "port" must be an integer'

    svc_t0 = util.log_start(log,
                            'start_service',
                            kvp=dict(host=host, port=port))

    # Create server
    services = services or SERVICES_DICT
    handler = api_class(services)
    processor = service_class.Processor(handler)
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()
    resource = TTwisted.ThriftResource(processor, pfactory, pfactory)
    site = twisted.web.server.Site(resource=resource)
    twisted.internet.reactor.listenTCP(port, site, interface=host)

    # Kill entire process group on shutdown
    if killprocgrp:
        twisted.internet.reactor.addSystemEventTrigger(
            'before', 'shutdown', functools.partial(kill_process_group,
                                                    log=log))

    # Run server
    sname = api_class.__name__
    shost = host or 'localhost'
    util.log_start(log, 'server', kvp=dict(name=sname, host=shost, port=port))
    t0 = util.log_start(log,
                        'twisted.internet.reactor.run',
                        level=logging.DEBUG)
    try:
        twisted.internet.reactor.run()
    except Exception as err:
        log.error('msg="Abort {} server on error"'.format(sname))
        util.log_end(log,
                     t0,
                     'twisted.internet.reactor.run',
                     status_code=1,
                     level=logging.ERROR,
                     kvp=dict(msg=err))
        raise
    finally:
        util.log_end(log, t0, 'twisted.internet.reactor.run')

    util.log_end(log, svc_t0, 'start_service', kvp=dict(host=host, port=port))
    return 0