basis/main.py
apeters 1d204f26b8 pre-Korves.Net
Signed-off-by: apeters <apeters@korves.net>
2025-05-21 08:05:07 +00:00

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())