fix: 拒绝环形 DAG 并避免无效工作流堵塞任务队列
This commit is contained in:
@@ -13,6 +13,7 @@ from fastapi import APIRouter, Depends, HTTPException
|
||||
|
||||
from wov_app.db import Database
|
||||
from wov_app.schemas import WorkflowCreate
|
||||
from wov_app.scheduler import topological_sort
|
||||
from wov_sdk.models import WorkflowDefinition
|
||||
|
||||
router = APIRouter(prefix="/api/admin/workflows", tags=["workflows"])
|
||||
@@ -32,10 +33,17 @@ def _slugify(value: str) -> str:
|
||||
|
||||
|
||||
def _validate_definition(raw: dict) -> WorkflowDefinition:
|
||||
"""解析并校验 DAG 定义,非法时转换为 422 HTTP 异常。"""
|
||||
"""解析并校验 DAG 定义,非法时转换为 422 HTTP 异常。
|
||||
|
||||
除 `WorkflowDefinition.validate()` 的结构校验(名称/版本/节点 ID 唯一/
|
||||
边引用存在)之外,还要求 DAG **可拓扑排序**:环形依赖虽然结构上合法,
|
||||
但执行时无法确定节点顺序,必须拒绝保存与发布(R04)。
|
||||
"""
|
||||
try:
|
||||
definition = WorkflowDefinition.from_dict(raw)
|
||||
definition.validate()
|
||||
# 环形 DAG(含自环)在这里以 "workflow contains a cycle" 被拒绝。
|
||||
topological_sort(definition)
|
||||
return definition
|
||||
except (KeyError, TypeError, ValueError) as exc:
|
||||
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
||||
@@ -119,6 +127,12 @@ def publish_workflow(workflow_id: str, db: Database = Depends(_get_db)) -> dict:
|
||||
raise HTTPException(status_code=404, detail="workflow not found")
|
||||
if workflow["latest_version"] == 0:
|
||||
raise HTTPException(status_code=422, detail="workflow has no version")
|
||||
# 发布前重新校验待发布版本:历史遗留的无效定义(例如修复前保存的环形 DAG)
|
||||
# 不能进入用户应用中心,否则创建出来的任务会在执行期失败(R04)。
|
||||
latest = db.get_latest_workflow_version(workflow_id)
|
||||
if latest is None:
|
||||
raise HTTPException(status_code=422, detail="workflow has no version")
|
||||
_validate_definition(latest["definition"])
|
||||
# 发布只是状态切换,不修改已保存的版本数据。
|
||||
db.upsert_workflow(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user