class UnixClientServer:
    temp = None
    sock = None
    server = None
    channel = None

    async def __aenter__(self):
        self.temp = tempfile.mkdtemp()
        self.sock = os.path.join(self.temp, 'grpclib.sock')

        dummy_service = DummyService()

        self.server = Server([dummy_service])
        await self.server.start(path=self.sock)

        self.channel = Channel(path=self.sock)
        dummy_stub = DummyServiceStub(self.channel)
        return dummy_service, dummy_stub

    async def __aexit__(self, *exc_info):
        self.server.close()
        await self.server.wait_closed()
        self.channel.close()
        if os.path.exists(self.sock):
            os.unlink(self.sock)
        if os.path.exists(self.temp):
            os.rmdir(self.temp)
Example #2
0
class ClientServer:
    server = None
    channel = None

    def __init__(self, *, loop):
        self.loop = loop

    async def __aenter__(self):
        host = '127.0.0.1'
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.bind(('127.0.0.1', 0))
            _, port = s.getsockname()

        dummy_service = DummyService()

        self.server = Server([dummy_service], loop=self.loop)
        await self.server.start(host, port)

        self.channel = Channel(host=host, port=port, loop=self.loop)
        dummy_stub = DummyServiceStub(self.channel)
        return dummy_service, dummy_stub

    async def __aexit__(self, *exc_info):
        self.server.close()
        await self.server.wait_closed()
        self.channel.close()
Example #3
0
def main():
    # setup judge
    judgeenv.load_env(cli=True)
    executors.load_executors()
    print('Running grpc judge server ...')
    logging.basicConfig(
        filename=judgeenv.log_file,
        level=logging.INFO,
        format='%(levelname)s %(asctime)s %(module)s %(message)s')
    for warning in judgeenv.startup_warnings:
        print(ansi_style('#ansi[Warning: %s](yellow)' % warning))
    del judgeenv.startup_warnings
    print()

    judge = LocalJudge()

    loop = asyncio.get_event_loop()

    server = Server([DmojService(judge)], loop=loop)

    host, port = '127.0.0.1', 5001
    loop.run_until_complete(server.start(host, port))
    print('Serving on {}:{}'.format(host, port))
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    server.close()
    loop.run_until_complete(server.wait_closed())
    loop.close()
Example #4
0
def channel_fixture(loop, port):
    services = [DummyService()]
    services = ServerReflection.extend(services)

    server = Server(services, loop=loop)
    loop.run_until_complete(server.start(port=port))

    channel = Channel(port=port, loop=loop)
    try:
        yield channel
    finally:
        channel.close()
        server.close()
        loop.run_until_complete(server.wait_closed())
Example #5
0
    def run(self):
        loop = asyncio.get_event_loop()
        server = Server([BotNode()], loop=loop)

        host, port = '0.0.0.0', 50051
        loop.run_until_complete(server.start(host, port))
        logger.debug(f'Serving on {host}:{port}')
        try:
            loop.run_forever()
        except KeyboardInterrupt:
            pass
        server.close()
        loop.run_until_complete(server.wait_closed())
        loop.close()
Example #6
0
def main():
    loop = asyncio.get_event_loop()

    server = Server([Greeter()], loop=loop, codec=JSONCodec)
    host, port = '127.0.0.1', 50051
    loop.run_until_complete(server.start(host, port))

    print('Serving on {}:{}'.format(host, port))
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    server.close()
    loop.run_until_complete(server.wait_closed())
    loop.close()
Example #7
0
def mainCode():
    count = 0
    loop = asyncio.get_event_loop()
    #server = Server([Emotion_recognizer(count)], loop=loop)
    server = Server([Emotion_recognizer()], loop=loop)

    host, port = '127.0.0.1', 50051
    loop.run_until_complete(server.start(host, port))
    print('Serving on {}:{}'.format(host, port))
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    server.close()
    loop.run_until_complete(server.wait_closed())
    loop.close()
Example #8
0
class ServerWire(Wire):
    """

    .. wire:: harness.wires.grpclib.server.ServerWire
      :type: output
      :runtime: python
      :config: harness.grpc.Server
      :requirements:
        grpclib
        protobuf

    """

    _config: grpc_pb2.Server
    server: Server

    def __init__(self, handlers: List["_Servable"]):
        self.handlers = handlers

    def configure(self, value: grpc_pb2.Server):
        assert isinstance(value, grpc_pb2.Server), type(value)
        self._config = value

        handlers = list(self.handlers)
        if not any(isinstance(h, Health) for h in handlers):
            handlers.append(Health())
        handlers = ServerReflection.extend(handlers)

        self.server = Server(handlers)
        listen(self.server, RecvRequest, _recv_request)
        listen(self.server, SendTrailingMetadata, _send_trailing_metadata)

    async def __aenter__(self):
        await self.server.start(self._config.bind.host, self._config.bind.port)
        _log.info(
            "%s started: addr=%s:%d",
            self.__class__.__name__,
            self._config.bind.host,
            self._config.bind.port,
        )

    def close(self):
        self.server.close()

    async def wait_closed(self):
        await self.server.wait_closed()
Example #9
0
class ClientServer:
    server = None

    def __init__(self, *, loop):
        self.loop = loop

    async def __aenter__(self):
        host = '127.0.0.1'
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.bind(('127.0.0.1', 0))
            _, port = s.getsockname()

        bombed = Bombed()

        self.server = Server([bombed], loop=self.loop)
        await self.server.start(host, port)

        channel = Channel(host=host, port=port, loop=self.loop)
        stub = BombedStub(channel)
        return bombed, stub

    async def __aexit__(self, *exc_info):
        self.server.close()
        await self.server.wait_closed()
Example #10
0
class App:
    def __init__(self, debug=False):
        self.debug = debug
        if not self.debug:
            uvloop.install()

        self.loop = asyncio.get_event_loop()
        self.prepared = False
        self.proxyman = ProxyMan()

    def _init_config(self):
        self.config = {
            "GRPC_HOST": os.getenv("SS_GRPC_HOST", "127.0.0.1"),
            "GRPC_PORT": os.getenv("SS_GRPC_PORT", "5000"),
            "SENTRY_DSN": os.getenv("SS_SENTRY_DSN"),
            "API_ENDPOINT": os.getenv("SS_API_ENDPOINT"),
            "LOG_LEVEL": os.getenv("SS_LOG_LEVEL", "info"),
            "SYNC_TIME": int(os.getenv("SS_SYNC_TIME", 60)),
            "STREAM_DNS_SERVER": os.getenv("SS_STREAM_DNS_SERVER"),
            "METRICS_PORT": os.getenv("SS_METRICS_PORT"),
            "TIME_OUT_LIMIT": int(os.getenv("SS_TIME_OUT_LIMIT", 60)),
            "USER_TCP_CONN_LIMIT": int(os.getenv("SS_TCP_CONN_LIMIT", 60)),
        }

        self.grpc_host = self.config["GRPC_HOST"]
        self.grpc_port = self.config["GRPC_PORT"]
        self.log_level = self.config["LOG_LEVEL"]
        self.sync_time = self.config["SYNC_TIME"]
        self.sentry_dsn = self.config["SENTRY_DSN"]
        self.api_endpoint = self.config["API_ENDPOINT"]
        self.timeout_limit = self.config["TIME_OUT_LIMIT"]
        self.stream_dns_server = self.config["STREAM_DNS_SERVER"]
        self.user_tcp_conn_limit = self.config["USER_TCP_CONN_LIMIT"]

        self.metrics_port = self.config["METRICS_PORT"]
        self.use_sentry = True if self.sentry_dsn else False
        self.use_json = False if self.api_endpoint else True
        self.use_grpc = True if self.grpc_host and self.grpc_port else False

    def _init_logger(self):
        """
        basic log config
        """
        log_levels = {
            "CRITICAL": 50,
            "ERROR": 40,
            "WARNING": 30,
            "INFO": 20,
            "DEBUG": 10,
        }
        if self.debug:
            level = 10
        else:
            level = log_levels.get(self.log_level.upper(), 10)
        logging.basicConfig(
            format="[%(levelname)s]%(asctime)s - %(filename)s - %(funcName)s "
            "line:%(lineno)d: - %(message)s",
            level=level,
        )

    def _init_memory_db(self):

        for _, model in inspect.getmembers(models, inspect.isclass):
            if issubclass(model, BaseModel) and model != BaseModel:
                model.create_table()
                logging.info(f"正在创建{model}内存数据库")

    def _init_sentry(self):
        if not self.use_sentry:
            return
        sentry_sdk.init(dsn=self.sentry_dsn,
                        integrations=[AioHttpIntegration()])
        logging.info("Init Sentry Client...")

    def _prepare(self):
        if self.prepared:
            return
        self._init_config()
        self._init_logger()
        self._init_memory_db()
        self._init_sentry()
        self.loop.add_signal_handler(signal.SIGTERM, self.shutdown)
        self.prepared = True

    async def start_grpc_server(self):

        self.grpc_server = Server([AioShadowsocksServicer()], loop=self.loop)
        listen(self.grpc_server, RecvRequest, logging_grpc_request)
        await self.grpc_server.start(self.grpc_host, self.grpc_port)
        logging.info(f"Start grpc Server on {self.grpc_host}:{self.grpc_port}")

    async def start_metrics_server(self):
        app = web.Application()
        app.router.add_get("/metrics", aio.web.server_stats)
        runner = web.AppRunner(app)
        await runner.setup()
        self.metrics_server = web.TCPSite(runner, "0.0.0.0", self.metrics_port)
        await self.metrics_server.start()
        logging.info(
            f"Start Metrics Server At: http://0.0.0.0:{self.metrics_port}/metrics"
        )

    def run(self):
        self._prepare()

        if self.use_json:
            self.loop.create_task(self.proxyman.start_ss_json_server())
        else:
            self.loop.create_task(
                self.proxyman.start_remote_sync_server(self.api_endpoint,
                                                       self.sync_time))

        if self.use_grpc:
            self.loop.create_task(self.start_grpc_server())

        if self.metrics_port:
            self.loop.create_task(self.start_metrics_server())

        try:
            self.loop.run_forever()
        except KeyboardInterrupt:
            self.shutdown()

    def shutdown(self):
        logging.info("正在关闭所有ss server")
        self.proxyman.close_server()
        if self.use_grpc:
            self.grpc_server.close()
            logging.info(f"grpc server closed!")
        if self.metrics_port:
            self.loop.create_task(self.metrics_server.stop())
            logging.info(f"metrics server closed!")
        self.loop.stop()
Example #11
0
class App:
    def __init__(self, debug=False):
        if not debug:
            uvloop.install()
        self.loop = asyncio.get_event_loop()
        self.prepared = False

    def _init_config(self):
        self.config = {
            "GRPC_HOST": os.getenv("SS_GRPC_HOST"),
            "GRPC_PORT": os.getenv("SS_GRPC_PORT"),
            "SENTRY_DSN": os.getenv("SS_SENTRY_DSN"),
            "API_ENDPOINT": os.getenv("SS_API_ENDPOINT"),
            "LOG_LEVEL": os.getenv("SS_LOG_LEVEL", "info"),
            "SYNC_TIME": int(os.getenv("SS_SYNC_TIME", 60)),
            "TIME_OUT_LIMIT": int(os.getenv("SS_TIME_OUT_LIMIT", 60)),
            "USER_TCP_CONN_LIMIT": int(os.getenv("SS_TCP_CONN_LIMIT", 60)),
        }

        self.grpc_host = self.config["GRPC_HOST"]
        self.grpc_port = self.config["GRPC_PORT"]
        self.log_level = self.config["LOG_LEVEL"]
        self.sync_time = self.config["SYNC_TIME"]
        self.sentry_dsn = self.config["SENTRY_DSN"]
        self.api_endpoint = self.config["API_ENDPOINT"]
        self.timeout_limit = self.config["TIME_OUT_LIMIT"]
        self.user_tcp_conn_limit = self.config["USER_TCP_CONN_LIMIT"]

        self.use_json = False if self.api_endpoint else True
        self.use_grpc = True if self.grpc_host and self.grpc_port else False
        self.use_sentry = True if self.sentry_dsn else False

    def _init_logger(self):
        """
        basic log config
        """
        log_levels = {
            "CRITICAL": 50,
            "ERROR": 40,
            "WARNING": 30,
            "INFO": 20,
            "DEBUG": 10,
        }
        level = log_levels.get(self.log_level.upper(), 10)
        logging.basicConfig(
            format=
            "[%(levelname)s]%(asctime)s-%(name)s - %(funcName)s() - %(message)s",
            level=level,
        )

    def _init_memory_db(self):
        from shadowsocks.mdb import BaseModel, models

        for _, model in inspect.getmembers(models, inspect.isclass):
            if issubclass(model, BaseModel) and model != BaseModel:
                model.create_table()
                logging.info(f"正在创建{model}内存数据库")

    def _init_sentry(self):
        if not self.use_sentry:
            return
        self.sentry_client = raven.Client(self.sentry_dsn,
                                          transport=AioHttpTransport)
        self.loop.set_exception_handler(self.__sentry_exception_handler)
        logging.info("Init Sentry Client...")

    def _prepare(self):
        if self.prepared:
            return
        self._init_config()
        self._init_logger()
        self._init_memory_db()
        self._init_sentry()
        self.loop.add_signal_handler(signal.SIGTERM, self.shutdown)
        self.prepared = True

    def __sentry_exception_handler(self, loop, context):
        try:
            raise context["exception"]
        except TimeoutError:
            logging.error(f"socket timeout msg: {context['message']}")
        except Exception:
            logging.error(f"unhandled error msg: {context['message']}")
            self.sentry_client.captureException(**context)

    async def start_grpc_server(self):
        from shadowsocks.services import AioShadowsocksServicer

        self.grpc_server = Server([AioShadowsocksServicer()], loop=self.loop)
        await self.grpc_server.start(self.grpc_host, self.grpc_port)
        logging.info(f"Start Grpc Server on {self.grpc_host}:{self.grpc_port}")

    def start_json_server(self):
        from shadowsocks.mdb import models

        models.User.create_or_update_from_json("userconfigs.json")
        models.User.init_user_servers()

    def start_remote_sync_server(self):
        from shadowsocks.mdb import models

        try:
            models.User.create_or_update_from_remote(self.api_endpoint)
            models.UserServer.flush_metrics_to_remote(self.api_endpoint)
            models.User.init_user_servers()
        except Exception as e:
            logging.warning(f"sync user error {e}")
        self.loop.call_later(self.sync_time, self.start_remote_sync_server)

    def shutdown(self):
        from shadowsocks.mdb import models

        models.UserServer.shutdown()
        if self.use_grpc:
            self.grpc_server.close()
            logging.info(
                f"Grpc Server on {self.grpc_host}:{self.grpc_port} Closed!")

        self.loop.stop()

    def run(self):
        self._prepare()

        if self.use_json:
            self.start_json_server()
        else:
            self.start_remote_sync_server()

        if self.use_grpc:
            self.loop.create_task(self.start_grpc_server())

        try:
            self.loop.run_forever()
        except KeyboardInterrupt:
            logging.info("正在关闭所有ss server")
            self.shutdown()
Example #12
0
class App:
    def __init__(self, debug=False):
        self.debug = debug
        if not self.debug:
            uvloop.install()

        self.loop = asyncio.get_event_loop()
        self.prepared = False
        self.proxyman = ProxyMan()

    def _init_config(self):
        self.config = {
            "GRPC_HOST": os.getenv("SS_GRPC_HOST", "127.0.0.1"),
            "GRPC_PORT": os.getenv("SS_GRPC_PORT", "5000"),
            "SENTRY_DSN": os.getenv("SS_SENTRY_DSN"),
            "API_ENDPOINT": os.getenv("SS_API_ENDPOINT"),
            "LOG_LEVEL": os.getenv("SS_LOG_LEVEL", "info"),
            "SYNC_TIME": int(os.getenv("SS_SYNC_TIME", 60)),
            "STREAM_DNS_SERVER": os.getenv("SS_STREAM_DNS_SERVER"),
            "ENABLE_METRICS": bool(os.getenv("SS_ENABLE_METRICS", True)),
            "METRICS_PORT": os.getenv("SS_GRPC_PORT", "9888"),
            "TIME_OUT_LIMIT": int(os.getenv("SS_TIME_OUT_LIMIT", 60)),
            "USER_TCP_CONN_LIMIT": int(os.getenv("SS_TCP_CONN_LIMIT", 60)),
        }

        self.grpc_host = self.config["GRPC_HOST"]
        self.grpc_port = self.config["GRPC_PORT"]
        self.log_level = self.config["LOG_LEVEL"]
        self.sync_time = self.config["SYNC_TIME"]
        self.sentry_dsn = self.config["SENTRY_DSN"]
        self.api_endpoint = self.config["API_ENDPOINT"]
        self.timeout_limit = self.config["TIME_OUT_LIMIT"]
        self.stream_dns_server = self.config["STREAM_DNS_SERVER"]
        self.user_tcp_conn_limit = self.config["USER_TCP_CONN_LIMIT"]

        self.enable_metrics = self.config["ENABLE_METRICS"]
        self.metrics_port = self.config["METRICS_PORT"]
        self.use_sentry = True if self.sentry_dsn else False
        self.use_json = False if self.api_endpoint else True
        self.use_grpc = True if self.grpc_host and self.grpc_port else False

    def _init_logger(self):
        """
        basic log config
        """
        log_levels = {
            "CRITICAL": 50,
            "ERROR": 40,
            "WARNING": 30,
            "INFO": 20,
            "DEBUG": 10,
        }
        if self.debug:
            level = 10
        else:
            level = log_levels.get(self.log_level.upper(), 10)
        logging.basicConfig(
            format="[%(levelname)s]%(asctime)s - %(filename)s - %(funcName)s "
            "line:%(lineno)d: - %(message)s",
            level=level,
        )

    def _init_memory_db(self):
        from shadowsocks.mdb import BaseModel, models

        for _, model in inspect.getmembers(models, inspect.isclass):
            if issubclass(model, BaseModel) and model != BaseModel:
                model.create_table()
                logging.info(f"正在创建{model}内存数据库")

    # def _init_sentry(self):
    # TODO 升级到最新的sentry-sdk
    # def sentry_exception_handler(loop, context):
    #     try:
    #         raise context["exception"]
    #     except TimeoutError:
    #         logging.error(f"socket timeout msg: {context['message']}")
    #     except Exception:
    #         logging.error(f"unhandled error msg: {context['message']}")
    #         self.sentry_client.captureException(**context)

    # if not self.use_sentry:
    #     return
    # self.sentry_client = raven.Client(self.sentry_dsn, transport=AioHttpTransport)
    # self.loop.set_exception_handler(sentry_exception_handler)
    # logging.info("Init Sentry Client...")

    def _prepare(self):
        if self.prepared:
            return
        self._init_config()
        self._init_logger()
        self._init_memory_db()
        # self._init_sentry()
        self.loop.add_signal_handler(signal.SIGTERM, self.shutdown)
        self.prepared = True

    async def start_grpc_server(self):
        from shadowsocks.services import AioShadowsocksServicer

        self.grpc_server = Server([AioShadowsocksServicer()], loop=self.loop)
        await self.grpc_server.start(self.grpc_host, self.grpc_port)
        logging.info(f"Start Grpc Server on {self.grpc_host}:{self.grpc_port}")

    async def start_metrics_server(self):
        app = web.Application()
        app.router.add_get("/metrics", aio.web.server_stats)
        runner = web.AppRunner(app)
        await runner.setup()
        self.metrics_server = web.TCPSite(runner, "0.0.0.0", self.metrics_port)
        await self.metrics_server.start()
        logging.info(
            f"Start Metrics Server At: http://0.0.0.0:{self.metrics_port}/metrics"
        )

    def run(self):
        self._prepare()

        if self.use_json:
            self.loop.create_task(self.proxyman.start_ss_json_server())
        else:
            self.loop.create_task(
                self.proxyman.start_remote_sync_server(self.api_endpoint,
                                                       self.sync_time))

        if self.use_grpc:
            self.loop.create_task(self.start_grpc_server())

        if self.enable_metrics:
            self.loop.create_task(self.start_metrics_server())

        try:
            self.loop.run_forever()
        except KeyboardInterrupt:
            logging.info("正在关闭所有ss server")
            self.shutdown()

    def shutdown(self):
        self.proxyman.close_server()
        if self.use_grpc:
            self.grpc_server.close()
            logging.info(f"grpc server closed!")
        if self.enable_metrics:
            self.loop.create_task(self.metrics_server.stop())
            logging.info(f"metrics server closed!")
        pending = asyncio.all_tasks(self.loop)
        self.loop.run_until_complete(asyncio.gather(*pending))
        self.loop.stop()
Example #13
0
def main():
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    loop = asyncio.get_event_loop()
    logging.basicConfig(level=os.getenv('LOG_LEVEL', logging.INFO))
    logging.getLogger("asyncio").setLevel(logging.ERROR)
    logging.getLogger("aiohttp").setLevel(logging.ERROR)
    logging.getLogger("jaeger_tracing").setLevel(logging.ERROR)
    logger = logging.getLogger(__name__)
    ctx.logger = logger
    h = '0.0.0.0'

    # configuration
    config = os.getenv("CONFIG")
    if not config:
        raise EnvironmentError("no config file specified")
    if not os.path.exists(config):
        raise EnvironmentError("config file does not exist")
    logger.info("Reading configuration from {config}".format(**locals()))
    try:
        with open(config, "r") as cfg:
            config = ujson.load(cfg)
    except ValueError:
        raise EnvironmentError("could not parse config file")
    jsonschema.validate(config, schema)

    # tracer
    jport = os.getenv('JAEGER_AGENT_PORT')
    if jport:
        config = jaeger_client.Config(config={
            'sampler': {
                'type': 'const',
                'param': 1
            },
            'logging': True,
        },
                                      service_name='pyskull',
                                      validate=True)
        ctx.tracer = config.initialize_tracer()
        logger.info("jaeger started against {}:{}".format(
            os.getenv('JAEGER_AGENT_HOST'), jport))

    # http api server
    runner = None
    api_port = os.environ['HTTP_PORT']
    if api_port:
        from pyskull.http import routes, middlewares
        from aiohttp import web
        app = web.Application(middlewares=middlewares)
        app.add_routes(routes)
        runner = web.AppRunner(app)
        loop.run_until_complete(runner.setup())
        site = web.TCPSite(runner, h, int(api_port))
        loop.run_until_complete(site.start())
        logger.info("HTTP API started on {h}:{api_port}".format(**locals()))

    # grpc server
    gapi = None
    gport = os.getenv('GRPC_PORT')
    if gport:
        from pyskull import grpc as g
        from grpclib.server import Server
        gapi = Server([g.Greeter()], loop=loop)
        loop.run_until_complete(gapi.start('0.0.0.0', 50051))
        logger.info("gRPC started on {h}:{gport}".format(**locals()))

    # metrics server
    mserver = None
    metrics_port = os.environ['METRICS_PORT']
    if metrics_port:
        mserver = MetricsServer()
        loop.run_until_complete(mserver.start(h, metrics_port))
        logger.info("metrics started on {h}:{metrics_port}".format(**locals()))

    def killer(**kwargs):
        raise KeyboardInterrupt

    loop.add_signal_handler(signal.SIGINT,
                            lambda: asyncio.ensure_future(killer()))
    loop.add_signal_handler(signal.SIGTERM,
                            lambda: asyncio.ensure_future(killer()))
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        logger.info('shutting down')
        cleanup = []
        if runner:
            cleanup += [asyncio.ensure_future(runner.cleanup())]

        if gapi:
            gapi.close()
            cleanup += [asyncio.ensure_future(gapi.wait_closed())]

        if mserver:
            cleanup += [asyncio.ensure_future(mserver.stop())]

        loop.run_until_complete(asyncio.gather(*cleanup))
        loop.close()

        # allow for tracer to flush if enabled
        if ctx.tracer:
            time.sleep(2)
            ctx.tracer.close()
Example #14
0
class App:
    def __init__(self):
        uvloop.install()
        self.loop = asyncio.get_event_loop()
        self.loop.add_signal_handler(signal.SIGTERM, self.shutdown)

        self.config = {
            "API_ENDPOINT": os.getenv("SS_API_ENDPOINT"),
            "GRPC_HOST": os.getenv("SS_GRPC_HOST"),
            "GRPC_PORT": os.getenv("SS_GRPC_PORT"),
            "SYNC_TIME": int(os.getenv("SS_SYNC_TIME", 60)),
            "LOG_LEVEL": os.getenv("SS_LOG_LEVEL", "info"),
        }

        self.api_endpoint = self.config.get("API_ENDPOINT")
        self.grpc_host = self.config.get("GRPC_HOST")
        self.grpc_port = self.config.get("GRPC_PORT")

        self.use_json = False if self.api_endpoint else True
        self.use_grpc = True if self.grpc_host and self.grpc_port else False

        self._prepared = False

    def _init_logger_config(self):
        """
        basic log config
        """
        log_levels = {
            "CRITICAL": 50,
            "ERROR": 40,
            "WARNING": 30,
            "INFO": 20,
            "DEBUG": 10,
        }
        level = log_levels.get(self.config["LOG_LEVEL"].upper(), 10)
        logging.basicConfig(
            format=
            "[%(levelname)s]%(asctime)s-%(name)s - %(funcName)s() - %(message)s",
            level=level,
        )

    def _init_memory_db(self):
        for _, model in inspect.getmembers(models, inspect.isclass):
            if issubclass(model, BaseModel) and model != BaseModel:
                model.create_table()
                logging.info(f"正在创建{model}临时数据库")

    def _prepare(self):
        if self._prepared:
            return
        self._init_logger_config()
        self._init_memory_db()
        self._prepared = True

    def start_json_server(self):
        models.User.create_or_update_from_json("userconfigs.json")
        models.User.init_user_servers()

    def start_remote_sync_server(self):
        try:
            models.User.create_or_update_from_remote()
            models.UserServer.flush_data_to_remote()
            models.User.init_user_servers()
        except Exception as e:
            logging.warning(f"sync user error {e}")
        self.loop.call_later(self.config["SYNC_TIME"],
                             self.start_remote_sync_server)

    async def start_grpc_server(self):
        self.grpc_server = Server([AioShadowsocksServicer()], loop=self.loop)
        await self.grpc_server.start(self.grpc_host, self.grpc_port)
        logging.info(f"Start Grpc Server on {self.grpc_host}:{self.grpc_port}")

    def shutdown(self):
        models.UserServer.shutdown()
        if self.use_grpc:
            self.grpc_server.close()
            logging.info(
                f"Grpc Server on {self.grpc_host}:{self.grpc_port} Closed!")
        self.loop.stop()

    def run(self):
        self._prepare()

        if self.use_json:
            self.start_json_server()
        else:
            self.start_remote_sync_server()

        if self.use_grpc:
            self.loop.create_task(self.start_grpc_server())

        try:
            self.loop.run_forever()
        except KeyboardInterrupt:
            logging.info("正在关闭所有ss server")
            self.shutdown()
Example #15
0
    p.add_argument('host',
                   nargs='?',
                   const=1,
                   default=settings.GRPC_SERVER_HOST)
    p.add_argument('port',
                   nargs='?',
                   type=int,
                   const=1,
                   default=settings.GRPC_SERVER_PORT)
    args = p.parse_args()
    host = args.host
    port = args.port

    env = server = None
    loop = asyncio.get_event_loop()

    try:
        engine = loop.run_until_complete(init_engine())
        server = Server([BillingService(engine=engine)],
                        loop=asyncio.get_event_loop())
        loop.run_until_complete(server.start(host, port))
        stop = asyncio.Future()
        loop.add_signal_handler(signal.SIGTERM, stop.set_result, None)
        loop.run_until_complete(stop)
    except KeyboardInterrupt:
        pass
    finally:
        server.close() if server else None
        engine = loop.run_until_complete(engine.close())
        loop.run_until_complete(server.wait_closed()) if server else None