feat: 新增字画布节点 --story=135278474 - #850
Conversation
There was a problem hiding this comment.
Code Review 总结
本PR 实现了子画布(SubCanvas)功能,包括新增插件、基类重构、pipeline 定位逻辑增强、以及多个新增 API 端点。整体架构合理,基类提取(LoopBaseService)降低了重复代码。以下是发现的问题:
| 级别 | 数量 |
|---|---|
| 🚨 严重 | 1 |
| 4 |
主要问题:
get_node_outputs传入 QuerySet 而非实例,运行时必崩batch_get_task_states循环逐个查询任务状态,存在 N+1 性能问题requirements.txt中 PyPI 版本与本地 whl 冲突is_child_taskflow使用 CharField 表达布尔语义list_children_taskflowAPI 名暗示列出所有子任务,但实际只返回 subprocess 类型
| @@ -84,6 +87,7 @@ | |||
|
|
|||
There was a problem hiding this comment.
🚨 TaskInstance.objects.filter(...) 返回的是 QuerySet 而非单个实例,但 TaskNodeOperation.__init__ 期望接收 TaskInstance 实例。运行时会在访问 self.task_instance.instance_id 等属性时报错。应改为 .get(id=task_id, space_id=space_id)(并处理 DoesNotExist 异常)。
| task_id = ser.validated_data["task_id"] | ||
| space_id = ser.validated_data["space_id"] | ||
| node_ids = ser.validated_data["node_ids"] | ||
| task_instance = TaskInstance.objects.filter(id=task_id, space_id=space_id) |
There was a problem hiding this comment.
🚨 TaskInstance.objects.filter(...) 返回 QuerySet,而 TaskNodeOperation.__init__ 期望接收单个 TaskInstance 实例。运行时访问 self.task_instance.instance_id 时会报AttributeError。应改为 .get(id=task_id, space_id=space_id) 并处理 DoesNotExist。
|
|
||
| tasks = TaskInstance.objects.filter(id__in=task_id_list, space_id=space_id) | ||
| states_result = {} | ||
| for task in tasks: |
There was a problem hiding this comment.
⚡ 循环内逐个调用 get_task_states() 存在 N+1 问题。当 task_ids 列表较大时,每个任务都会触发独立的引擎状态查询。建议限制 task_ids 数量上限,或考虑批量查询方案。
| @@ -36,6 +36,10 @@ bk-notice-sdk==1.3.0 | |||
| # engine service | |||
| boto3==1.26.133 | |||
| bamboo-pipeline==3.29.9 | |||
There was a problem hiding this comment.
bamboo-pipeline==3.29.9(PyPI)与下方 ./packages/bamboo_pipeline-3.30.0-py3-none-any.whl 冲突,pip 行为不确定。应删除或注释掉此行。
There was a problem hiding this comment.
✅ 此问题已在最新提交 f970331 中解决——已移除冲突的 bamboo-pipeline==3.29.9 行。
| executor = serializers.CharField(help_text=_("执行者"), max_length=USER_NAME_MAX_LENGTH, required=False) | ||
| template_id = serializers.IntegerField(help_text=_("流程ID"), required=False) | ||
| label = serializers.CharField(help_text=_("标签名称"), required=False) | ||
| is_child_taskflow = serializers.CharField(help_text=_("过滤子任务"), required=False, default="false") |
There was a problem hiding this comment.
✨ is_child_taskflow 语义为布尔值,但使用 CharField(default="false")。建议改用 BooleanField(或至少 ChoiceField),让API 文档和类型更明确。
| if not children_task_ids: | ||
| return Response({"tasks": [], "relations": {}}, status=status.HTTP_200_OK) | ||
| queryset = TaskInstance.objects.filter( | ||
| id__in=children_task_ids, is_deleted=False, trigger_method=TaskTriggerMethod.subprocess.name |
There was a problem hiding this comment.
trigger_method=TaskTriggerMethod.subprocess.name 使得此 API 只返回子流程任务,子画布任务被排除。API 名称 list_children_taskflow 暗示会列出所有子任务,建议在文档或注释中明确说明。
There was a problem hiding this comment.
Code Review 总结
本PR 实现了子画布(SubCanvas)功能,包括新增 subcanvas_plugin、LoopBaseService 基类提取、pipeline 自动排版增强、以及多个新增查询 API。整体架构设计合理,重构提取有效降低了重复代码。
发现问题
| 级别 | 问题 | 位置 |
|---|---|---|
| 🚨 严重 | get_node_outputs 传入 QuerySet 而非实例,运行时必崩 |
views.py:536 |
| ⚡ 性能 | batch_get_task_states 循环内逐个查询状态(N+1) |
views.py:375 |
requirements.txt PyPI 包与本地 whl 同时存在,版本冲突 |
requirements.txt:38 |
|
| ✨ 改进 | is_child_taskflow 字段类型应使用 BooleanField |
serializers/task.py:231 |
list_children_taskflow 只过滤 subprocess 不含sub_canvas |
views.py:460 |
建议优先处理
- 必须修复:
get_node_outputs中.filter()改为.get() - 应当修复:
requirements.txt移除旧版bamboo-pipeline==3.29.9行
There was a problem hiding this comment.
Code Review 总结(增量审查)
本次增量审查针对新提交 f970331(fix: 修复测试问题),该提交仅包含一处变更:移除 requirements.txt 中冲突的 bamboo-pipeline==3.29.9 行。
已修复问题
| 状态 | 问题 | 位置 |
|---|---|---|
| ✅ 已解决 | PyPI bamboo-pipeline==3.29.9 与本地 whl 3.30.0 冲突 |
requirements.txt:38 |
仍存在的问题(未在本次提交中处理)
| 级别 | 问题 | 位置 |
|---|---|---|
| 🚨 严重 | get_node_outputs 传入 QuerySet 而非单实例 |
views.py:536 |
| ⚡ 性能 | batch_get_task_states 循环内逐个查询(N+1) |
views.py:375 |
list_children_taskflow 仅过滤 subprocess,不含 sub_canvas |
views.py:460 |
|
| ✨ 改进 | is_child_taskflow 应使用 BooleanField |
serializers/task.py:231 |
首要建议:修复 get_node_outputs 中 .filter() → .get() 的问题,这是运行时必崩的 bug。
No description provided.