Files
server-core/dispatcher.py
T
Pine 6edcec4048 feat: 统一入口 dispatcher(对外 opc.pinesound.cn)
- /api/* /uploads/* /SpXvScDiDT.txt → 培训子应用
- 其余 → 平台应用;驱动双子应用 lifespan
2026-08-23 22:36:00 +08:00

64 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""server-core 统一入口(dispatcher)—— 对外生产服务 opc.pinesound.cn 单入口。
同一端口服务平台应用与培训子应用,按路径路由:
/api/*、/uploads/*、/SpXvScDiDT.txt → 培训子应用(app.training,保留 /api 路由与独立 data/opc.db
其余(/auth /opc /admin /agents 等)→ 平台应用(app.main,身份 + 业务域)
启动(server-core 目录):
uv run uvicorn dispatcher:app --host 0.0.0.0 --port 8090 --reload
"""
from __future__ import annotations
import logging
from app.main import app as core_app
from app.training.main import app as training_app
logger = logging.getLogger(__name__)
ROUTE_TRAINING_PREFIXES = ("/api", "/uploads", "/SpXvScDiDT.txt")
class Dispatcher:
"""极简 ASGI 分发器:驱动子应用 lifespan(核心库初始化)+ 按路径路由。"""
def __init__(self, apps: list):
self._apps = apps
async def _run_lifespan(self, receive, send):
"""依次进入各子应用 lifespan(核心应用负责建表/种子),按启动/停止消息配对退出。"""
started: list = []
try:
while True:
message = await receive()
if message["type"] == "lifespan.startup":
for a in self._apps:
cm = a.router.lifespan_context(app=a)
await cm.__aenter__()
started.append(cm)
await send({"type": "lifespan.startup.complete"})
elif message["type"] == "lifespan.shutdown":
for cm in reversed(started):
await cm.__aexit__(None, None, None)
started = []
await send({"type": "lifespan.shutdown.complete"})
return
except BaseException:
for cm in reversed(started):
try:
await cm.__aexit__(None, None, None)
except Exception: # noqa: BLE001
pass
raise
async def __call__(self, scope, receive, send):
if scope["type"] == "lifespan":
await self._run_lifespan(receive, send)
return
path = scope.get("path", "")
target = training_app if path.startswith(ROUTE_TRAINING_PREFIXES) else core_app
await target(scope, receive, send)
app = Dispatcher([core_app, training_app])