mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 15:38:19 +08:00
fix(agent): map closed database worker to 503
This commit is contained in:
@@ -5,7 +5,6 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from app.api.dependencies.agent import (
|
from app.api.dependencies.agent import (
|
||||||
get_agent_chat_persistence,
|
|
||||||
get_agent_chat_service,
|
get_agent_chat_service,
|
||||||
get_message_query_service,
|
get_message_query_service,
|
||||||
)
|
)
|
||||||
@@ -53,7 +52,6 @@ from app.api.dependencies.workflow import (
|
|||||||
|
|
||||||
# 兼容聚合入口只显式列出既有 FastAPI 依赖,不向插件制造新的动态导出规则。
|
# 兼容聚合入口只显式列出既有 FastAPI 依赖,不向插件制造新的动态导出规则。
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"get_agent_chat_persistence",
|
|
||||||
"get_agent_chat_service",
|
"get_agent_chat_service",
|
||||||
"get_auth_service",
|
"get_auth_service",
|
||||||
"get_current_active_manage_user",
|
"get_current_active_manage_user",
|
||||||
|
|||||||
+10
-3
@@ -14,7 +14,10 @@ from app.adapters.observability.otel import build_observation_port
|
|||||||
from app.adapters.web.plugin.routes import FastAPIDynamicRouteRegistry
|
from app.adapters.web.plugin.routes import FastAPIDynamicRouteRegistry
|
||||||
from app.adapters.web.health import install_health_routes
|
from app.adapters.web.health import install_health_routes
|
||||||
from app.application.plugin.routes import configure_plugin_routes
|
from app.application.plugin.routes import configure_plugin_routes
|
||||||
from app.application.database import DatabaseWorkerOverloadedError
|
from app.application.database import (
|
||||||
|
DatabaseWorkerClosedError,
|
||||||
|
DatabaseWorkerOverloadedError,
|
||||||
|
)
|
||||||
from app.adapters.web.security.access import (
|
from app.adapters.web.security.access import (
|
||||||
configure_token_codec,
|
configure_token_codec,
|
||||||
verify_apikey,
|
verify_apikey,
|
||||||
@@ -234,9 +237,9 @@ async def localized_http_exception_handler(
|
|||||||
|
|
||||||
async def database_worker_overloaded_handler(
|
async def database_worker_overloaded_handler(
|
||||||
request: Request,
|
request: Request,
|
||||||
_exc: DatabaseWorkerOverloadedError,
|
_exc: DatabaseWorkerClosedError | DatabaseWorkerOverloadedError,
|
||||||
) -> JSONResponse:
|
) -> JSONResponse:
|
||||||
"""将数据库短事务背压映射为可重试的 503 响应。"""
|
"""将数据库 worker 暂不可用映射为可重试的 503 响应。"""
|
||||||
return await localized_http_exception_handler(
|
return await localized_http_exception_handler(
|
||||||
request,
|
request,
|
||||||
HTTPException(
|
HTTPException(
|
||||||
@@ -335,6 +338,10 @@ def create_app() -> FastAPI:
|
|||||||
DatabaseWorkerOverloadedError,
|
DatabaseWorkerOverloadedError,
|
||||||
database_worker_overloaded_handler,
|
database_worker_overloaded_handler,
|
||||||
)
|
)
|
||||||
|
_app.add_exception_handler(
|
||||||
|
DatabaseWorkerClosedError,
|
||||||
|
database_worker_overloaded_handler,
|
||||||
|
)
|
||||||
_app.add_exception_handler(
|
_app.add_exception_handler(
|
||||||
RequestValidationError,
|
RequestValidationError,
|
||||||
localized_validation_exception_handler,
|
localized_validation_exception_handler,
|
||||||
|
|||||||
@@ -23,7 +23,10 @@ from app.factory import (
|
|||||||
localized_unhandled_exception_handler,
|
localized_unhandled_exception_handler,
|
||||||
localized_validation_exception_handler,
|
localized_validation_exception_handler,
|
||||||
)
|
)
|
||||||
from app.application.database import DatabaseWorkerOverloadedError
|
from app.application.database import (
|
||||||
|
DatabaseWorkerClosedError,
|
||||||
|
DatabaseWorkerOverloadedError,
|
||||||
|
)
|
||||||
from app.runtime.localization import LocaleHelper
|
from app.runtime.localization import LocaleHelper
|
||||||
from app.runtime.config import settings
|
from app.runtime.config import settings
|
||||||
from app.schemas.common import JsonData
|
from app.schemas.common import JsonData
|
||||||
@@ -67,6 +70,10 @@ def api_app() -> FastAPI:
|
|||||||
DatabaseWorkerOverloadedError,
|
DatabaseWorkerOverloadedError,
|
||||||
database_worker_overloaded_handler,
|
database_worker_overloaded_handler,
|
||||||
)
|
)
|
||||||
|
app.add_exception_handler(
|
||||||
|
DatabaseWorkerClosedError,
|
||||||
|
database_worker_overloaded_handler,
|
||||||
|
)
|
||||||
from fastapi.exceptions import RequestValidationError
|
from fastapi.exceptions import RequestValidationError
|
||||||
|
|
||||||
app.add_exception_handler(
|
app.add_exception_handler(
|
||||||
@@ -125,6 +132,11 @@ def api_app() -> FastAPI:
|
|||||||
"""模拟数据库短事务容量耗尽。"""
|
"""模拟数据库短事务容量耗尽。"""
|
||||||
raise DatabaseWorkerOverloadedError("worker full")
|
raise DatabaseWorkerOverloadedError("worker full")
|
||||||
|
|
||||||
|
@app.get("/database-closed")
|
||||||
|
async def get_database_closed() -> None:
|
||||||
|
"""模拟数据库 worker 在关闭态拒绝新任务。"""
|
||||||
|
raise DatabaseWorkerClosedError("worker closed")
|
||||||
|
|
||||||
@app.get("/native", response_model=None)
|
@app.get("/native", response_model=None)
|
||||||
async def get_native_response() -> dict[str, bool]:
|
async def get_native_response() -> dict[str, bool]:
|
||||||
"""返回显式旁路的原生 JSON 协议。"""
|
"""返回显式旁路的原生 JSON 协议。"""
|
||||||
@@ -219,6 +231,22 @@ async def test_database_worker_overload_is_retryable_service_unavailable(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_database_worker_closed_is_retryable_service_unavailable(
|
||||||
|
api_app: FastAPI,
|
||||||
|
):
|
||||||
|
"""数据库 worker 关闭态应返回 503,而不是落入通用 500。"""
|
||||||
|
async with make_client(api_app) as client:
|
||||||
|
response = await client.get("/database-closed")
|
||||||
|
|
||||||
|
assert response.status_code == 503
|
||||||
|
assert response.headers["retry-after"] == "1"
|
||||||
|
assert response.json() == {
|
||||||
|
"success": False,
|
||||||
|
"message": "服务当前繁忙,请稍后重试",
|
||||||
|
"data": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"path",
|
"path",
|
||||||
[
|
[
|
||||||
|
|||||||
Reference in New Issue
Block a user