|
|
@@ -398,9 +398,14 @@ async def restart_serving(task_id: str, user_id: str = "") -> dict[str, Any]:
|
|
|
return {"error": "模型文件路径丢失,无法重启,请重新部署"}
|
|
|
|
|
|
output_path = record.output_path
|
|
|
+ original_port = record.port # 记住原端口,尽量复用
|
|
|
|
|
|
- # 分配新端口
|
|
|
- port = await _allocate_port()
|
|
|
+ # 优先复用原端口,如果被其他 pending/running 服务占了才重新分配
|
|
|
+ if original_port:
|
|
|
+ port_available = await _check_port_available(original_port)
|
|
|
+ port = original_port if port_available else await _allocate_port()
|
|
|
+ else:
|
|
|
+ port = await _allocate_port()
|
|
|
|
|
|
# 更新状态为 pending,标记正在重启
|
|
|
await _update_deploy_status(task_id, "pending", port=port)
|
|
|
@@ -520,6 +525,19 @@ async def _allocate_port() -> int:
|
|
|
raise RuntimeError(f"无可用端口({_SERVE_PORT_MIN}-{_SERVE_PORT_MAX} 全部占用)")
|
|
|
|
|
|
|
|
|
+async def _check_port_available(port: int) -> bool:
|
|
|
+ """检查指定端口是否可被复用(没有被其他 pending/running 服务占用)。"""
|
|
|
+ async with async_session() as session:
|
|
|
+ result = await session.execute(
|
|
|
+ select(DeployTaskModel.id).where(
|
|
|
+ DeployTaskModel.deploy_mode == "serve",
|
|
|
+ DeployTaskModel.status.in_(["pending", "running"]),
|
|
|
+ DeployTaskModel.port == port,
|
|
|
+ )
|
|
|
+ )
|
|
|
+ return result.first() is None
|
|
|
+
|
|
|
+
|
|
|
async def _run_remote_export(task_id: str, job_id: str, merge_with_base: bool, export_format: str) -> dict:
|
|
|
"""通过 SSH 在远程容器执行模型合并/导出。"""
|
|
|
remote_cmd = (
|