feat: Host 中间件租户路由(纯ASGI覆盖WS/未知404/停用503暂停页/health豁免)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,9 @@
|
||||
"""路由取当前租户运行时——Task 5b→7 的过渡兜底。
|
||||
"""路由取当前租户运行时——纯访问器(Task 7)。
|
||||
|
||||
Task 7 的 Host 中间件上线前,没有人为请求挂 ``state.tenant``。本助手的
|
||||
兜底规则 = state 里有租户用 state 的(中间件灰度接入即生效);没有则用
|
||||
``app.state.default_runtime``(lifespan 预热的默认租户 jiancai),API 测试
|
||||
与直连(无 Host 语义)在 5b→7 过渡期不断。
|
||||
|
||||
已知过渡限制(记录在案,Task 7 一并解决):默认租户经 registry_reload
|
||||
热切换后 default_runtime 仍指向旧 runtime——过渡期不修,Task 7 中间件
|
||||
按请求 Host 重新 resolve 后本模块整体删除。
|
||||
TenantHostMiddleware(纯 ASGI,http 与 websocket 双覆盖)保证凡到达路由
|
||||
的请求 ``state.tenant`` 必已就位;唯一例外是平台级豁免路径(/health),
|
||||
而它不访问租户资源。本模块不再有任何兜底——state 无租户即 raise,把
|
||||
"中间件没挂上/被绕过"这类装配错误炸在第一现场而不是静默串库。
|
||||
"""
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
@@ -20,13 +16,10 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
def get_runtime(request_or_ws: Request | WebSocket) -> "TenantRuntime":
|
||||
"""state.tenant 优先,缺省落 app.state.default_runtime(Task 7 删)。"""
|
||||
"""读 state.tenant(中间件写入);缺失即装配错误,清晰失败。"""
|
||||
runtime = getattr(request_or_ws.state, "tenant", None)
|
||||
if runtime is not None:
|
||||
return runtime
|
||||
runtime = getattr(request_or_ws.app.state, "default_runtime", None)
|
||||
if runtime is None or runtime.session_factory is None:
|
||||
if runtime is None:
|
||||
raise RuntimeError(
|
||||
"默认租户运行时未就绪——lifespan 未运行、未预热 default_runtime,"
|
||||
"或 registry_reload 已 dispose 旧 runtime(过渡期限制,Task 7 解决)")
|
||||
"请求 state 里没有租户运行时——TenantHostMiddleware 未覆盖该"
|
||||
"请求(中间件未挂载,或豁免路径访问了租户资源)")
|
||||
return runtime
|
||||
|
||||
Reference in New Issue
Block a user