82 lines
2.3 KiB
Python
82 lines
2.3 KiB
Python
import asyncio
|
|
import signal
|
|
import ssl
|
|
import sys
|
|
|
|
from components.cluster.cluster import cluster
|
|
from components.web import *
|
|
from contextlib import asynccontextmanager
|
|
from hypercorn.asyncio import serve
|
|
from hypercorn.config import Config
|
|
from hypercorn.middleware import ProxyFixMiddleware
|
|
|
|
hypercorn_config = Config()
|
|
hypercorn_config.bind = [defaults.HYPERCORN_BIND]
|
|
hypercorn_config.certfile = defaults.TLS_CERTFILE
|
|
hypercorn_config.keyfile = defaults.TLS_KEYFILE
|
|
hypercorn_config.include_server_header = False
|
|
hypercorn_config.server_names = defaults.HOSTNAME
|
|
hypercorn_config.ciphers = "ECDHE+AESGCM"
|
|
hypercorn_shutdown_event = asyncio.Event()
|
|
|
|
|
|
def handle_shutdown() -> None:
|
|
hypercorn_shutdown_event.set()
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan():
|
|
def _exception_handler(loop, context):
|
|
exception = context.get("exception")
|
|
if isinstance(exception, ssl.SSLError) or isinstance(
|
|
exception, asyncio.sslproto._SSLProtocolTransport
|
|
):
|
|
pass
|
|
elif isinstance(exception, OSError) and exception.errno == 99:
|
|
print("ERROR: Unable to bind to an address")
|
|
hypercorn_shutdown_event.set()
|
|
else:
|
|
loop.default_exception_handler(context)
|
|
|
|
loop = asyncio.get_running_loop()
|
|
loop.set_exception_handler(_exception_handler)
|
|
|
|
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
loop.add_signal_handler(sig, handle_shutdown)
|
|
try:
|
|
yield
|
|
finally:
|
|
print("Lifespan ended")
|
|
sys.exit(0)
|
|
|
|
|
|
async def main():
|
|
async with lifespan():
|
|
tasks = [
|
|
asyncio.create_task(
|
|
serve(
|
|
ProxyFixMiddleware(app, mode="legacy", trusted_hops=1),
|
|
hypercorn_config,
|
|
shutdown_trigger=hypercorn_shutdown_event.wait,
|
|
),
|
|
name="qrt",
|
|
),
|
|
asyncio.create_task(
|
|
cluster.run(shutdown_trigger=hypercorn_shutdown_event),
|
|
name="cluster",
|
|
),
|
|
]
|
|
|
|
await hypercorn_shutdown_event.wait()
|
|
|
|
print("Shutting down")
|
|
|
|
for task in tasks:
|
|
task.cancel()
|
|
|
|
async with asyncio.timeout(1):
|
|
await asyncio.gather(*tasks, return_exceptions=True)
|
|
|
|
|
|
asyncio.run(main())
|