Skip to content

Commit

Permalink
feat: 任务调试历史查询 & 交互优化 #23
Browse files Browse the repository at this point in the history
  • Loading branch information
normal-wls committed Sep 18, 2024
1 parent 756bb03 commit 90aed08
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 22 deletions.
19 changes: 11 additions & 8 deletions bkflow/apigw/docs/zh/create_mock_task.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@

#### 接口参数

| 字段 | 类型 | 必选 | 描述 |
|-------------|--------|----|----------------------------------------------------------------------------|
| template_id | int || 模板id |
| name | string || 任务名 |
| creator | string || 创建者 |
| description | string || 描述 |
| constants | dict || 任务启动参数 |
| mock_data | dict || mock 数据,包含 nodes(mock 执行选中的节点) 和 outputs(mock 执行对应节点的 mock 数据,没有则表示不 mock) |
| 字段 | 类型 | 必选 | 描述 |
|-------------|--------|----|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| template_id | int || 模板id |
| name | string || 任务名 |
| creator | string || 创建者 |
| description | string || 描述 |
| constants | dict || 任务启动参数 |
| mock_data | dict || mock 数据,包含 nodes(mock 任务使用 mock 执行的节点),outputs(可选参数,mock 执行对应节点的节点输出),mock_data_ids(mock 执行对应节点使用的 mock 数据 id,如果 outputs 没有传参,则会自动将创建任务时对应的 mock 数据 作为 outputs) |

### 请求参数示例

Expand All @@ -38,6 +38,9 @@
"nd7927122ef6310eb309c2c8d3f70c23": {
"callback_data": "abc"
}
},
"mock_data_ids": {
"nd7927122ef6310eb309c2c8d3f70c23": 1
}
}
}
Expand Down
28 changes: 23 additions & 5 deletions bkflow/apigw/serializers/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

from bkflow.constants import MAX_LEN_OF_TASK_NAME, USER_NAME_MAX_LENGTH
from bkflow.pipeline_web.parser.validator import validate_web_pipeline_tree
from bkflow.template.models import TemplateMockData
from bkflow.utils.strings import standardize_pipeline_node_name


Expand All @@ -35,11 +36,10 @@ class CreateTaskSerializer(serializers.Serializer):


class TaskMockDataSerializer(serializers.Serializer):
nodes = serializers.ListSerializer(
help_text=_("要 Mock 执行的节点 ID 列表"), child=serializers.CharField(), default=[]
)
outputs = serializers.JSONField(
help_text=_('节点 Mock 输出, 形如{"node_id": {"output1": "output_value1"}}'), default={}
nodes = serializers.ListSerializer(help_text=_("要 Mock 执行的节点 ID 列表"), child=serializers.CharField(), default=[])
outputs = serializers.JSONField(help_text=_('节点 Mock 输出, 形如{"node_id": {"output1": "output_value1"}}'), default={})
mock_data_ids = serializers.JSONField(
help_text=_("节点 Mock 数据,当 outputs 为空时会提取对应 mock_data_ids 设置 outputs,否则仅记录作用"), default={}
)


Expand All @@ -58,6 +58,24 @@ class CreateMockTaskWithPipelineTreeSerializer(CreateMockTaskBaseSerializer):
class CreateMockTaskWithTemplateIdSerializer(CreateMockTaskBaseSerializer):
template_id = serializers.IntegerField(help_text=_("模版ID"))

def validate(self, attrs):
if attrs["mock_data"]["mock_data_ids"] and not attrs["mock_data"]["outputs"]:
mock_data = TemplateMockData.objects.filter(
template_id=attrs["template_id"], id__in=list(attrs["mock_data"]["mock_data_ids"].values())
).values("id", "data")
mock_data = {item["id"]: item["data"] for item in mock_data}
outputs = {}
for node_id, mock_data_id in attrs["mock_data"]["mock_data_ids"].items():
if node_id not in attrs["mock_data"].get("nodes"):
continue
if mock_data_id not in mock_data:
raise serializers.ValidationError(
f"mock data of node {node_id} with mock_data_id {mock_data_id} not found"
)
outputs[node_id] = mock_data[mock_data_id].get("data", {})
attrs["mock_data"]["outputs"] = outputs
return attrs


class CreateTaskWithoutTemplateSerializer(serializers.Serializer):
name = serializers.CharField(help_text=_("任务名"), max_length=MAX_LEN_OF_TASK_NAME, required=False)
Expand Down
4 changes: 2 additions & 2 deletions bkflow/task/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class AutoRetryNodeStrategyAdmin(admin.ModelAdmin):

@admin.register(models.TaskMockData)
class TaskMockDataAdmin(admin.ModelAdmin):
list_display = ["id", "taskflow_id", "data"]
search_fields = ["taskflow_id"]
list_display = ["id", "taskflow_id", "mock_data_ids", "data"]
search_fields = ["taskflow_id", "mock_data_ids"]


admin.site.register(TaskOperationRecord, BaseOperateRecordAdmin)
18 changes: 18 additions & 0 deletions bkflow/task/migrations/0009_taskmockdata_mock_data_ids.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.15 on 2024-09-14 08:21

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('task', '0008_alter_taskoperationrecord_instance_id'),
]

operations = [
migrations.AddField(
model_name='taskmockdata',
name='mock_data_ids',
field=models.JSONField(default=dict, verbose_name='task mock data ids'),
),
]
14 changes: 7 additions & 7 deletions bkflow/task/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ def create_instance(self, *args, **kwargs):
new_mock_data["outputs"] = {
act_mappings[node_id]: outputs for node_id, outputs in mock_data.get("outputs", {}).items()
}
TaskMockData.objects.create(taskflow_id=instance.id, data=new_mock_data)
TaskMockData.objects.create(
taskflow_id=instance.id, data=new_mock_data, mock_data_ids=mock_data.get("mock_data_ids", {})
)
# create auto retry strategy
arn_creator = AutoRetryNodeStrategyCreator(taskflow_id=instance.id, root_pipeline_id=instance.instance_id)
arn_creator.batch_create_strategy(pipeline_tree)
Expand Down Expand Up @@ -149,12 +151,8 @@ class TaskInstance(models.Model):
is_deleted = models.BooleanField("是否已经删除", default=False, help_text="表示当前实例是否删除")
is_expired = models.BooleanField("是否已经过期", default=False, help_text="运行时被定期清理即为过期")
snapshot_id = models.BigIntegerField(verbose_name="实例结构数据ID", null=True, blank=True, db_index=True)
execution_snapshot_id = models.BigIntegerField(
verbose_name="用于实例执行的结构数据ID", null=True, blank=True, db_index=True
)
tree_info_id = models.BigIntegerField(
verbose_name="提前计算好的一些流程结构数据ID", null=True, blank=True, db_index=True
)
execution_snapshot_id = models.BigIntegerField(verbose_name="用于实例执行的结构数据ID", null=True, blank=True, db_index=True)
tree_info_id = models.BigIntegerField(verbose_name="提前计算好的一些流程结构数据ID", null=True, blank=True, db_index=True)
extra_info = models.JSONField(verbose_name="额外信息", default=dict)

objects = TaskInstanceManager()
Expand Down Expand Up @@ -375,6 +373,7 @@ class TaskMockData(models.Model):
id = models.BigAutoField(verbose_name="ID", primary_key=True)
taskflow_id = models.BigIntegerField(verbose_name="taskflow id", db_index=True)
data = models.JSONField(verbose_name="task mock data")
mock_data_ids = models.JSONField(verbose_name="task mock data ids", default=dict)
create_time = models.DateTimeField("创建时间", auto_now_add=True, db_index=True)

class Meta:
Expand All @@ -386,5 +385,6 @@ def to_json(self):
"id": self.id,
"taskflow_id": self.taskflow_id,
"data": self.data,
"mock_data_ids": self.mock_data_ids,
"create_time": self.create_time,
}

0 comments on commit 90aed08

Please sign in to comment.