import os import logging import signal import sys from typing import List import ssl from asyncio import run, gather import asyncio from lib.backend import Backend from lib.metrics import Metrics from aiohttp import web log = logging.getLogger(__file__) def _setup_signal_handlers(): """Setup signal handlers to log when process receives termination signals.""" def signal_handler(signum, frame): sig_name = signal.Signals(signum).name log.error(f"SIGNAL RECEIVED: {sig_name} ({signum}) - process is being terminated") sys.stdout.flush() sys.stderr.flush() sys.exit(128 + signum) # Handle common termination signals for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP]: try: signal.signal(sig, signal_handler) except (OSError, ValueError): pass # Some signals may not be available def start_server(backend: Backend, routes: List[web.RouteDef], **kwargs): _setup_signal_handlers() try: log.debug("getting certificate...") use_ssl = os.environ.get("USE_SSL", "false") == "true" if use_ssl is True: ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain( certfile="/etc/instance.crt", keyfile="/etc/instance.key", ) else: ssl_context = None async def main(): log.debug("starting server...") app = web.Application() app.add_routes(routes) runner = web.AppRunner(app) await runner.setup() site = web.TCPSite( runner, ssl_context=ssl_context, port=int(os.environ["WORKER_PORT"]), **kwargs ) await gather(site.start(), backend._start_tracking()) run(main()) except Exception as e: err_msg = f"PyWorker failed to launch: {e}" log.error(err_msg) async def beacon(): metrics = Metrics() metrics._set_version(getattr(backend, "version", "0")) metrics._set_mtoken(getattr(backend, "mtoken", "")) try: while True: metrics._model_errored(err_msg) await metrics._Metrics__send_metrics_and_reset() await asyncio.sleep(10) finally: await metrics.aclose() run(beacon())