diff --git a/dbm-ui/backend/env/dev.py b/dbm-ui/backend/env/dev.py index 8d7c186ebb..3d2dae04fa 100644 --- a/dbm-ui/backend/env/dev.py +++ b/dbm-ui/backend/env/dev.py @@ -23,4 +23,4 @@ FAKE_RESOURCE_APPLY_ENABLE = get_type_env(key="FAKE_RESOURCE_APPLY_ENABLE", _type=bool, default=False) # 跳过审批开关,默认关闭,方便本地联调 -ITSM_FLOW_SKIP = get_type_env(key="ITSM_FLOW_SKIP", _type=str, default=False) +ITSM_FLOW_SKIP = get_type_env(key="ITSM_FLOW_SKIP", _type=bool, default=False) diff --git a/dbm-ui/backend/ticket/apps.py b/dbm-ui/backend/ticket/apps.py index 044d806e3f..70cc495143 100644 --- a/dbm-ui/backend/ticket/apps.py +++ b/dbm-ui/backend/ticket/apps.py @@ -11,7 +11,7 @@ import logging from django.apps import AppConfig -from django.db.models.signals import post_migrate +from django.db.models.signals import post_migrate, post_save logger = logging.getLogger("root") @@ -31,8 +31,11 @@ class TicketConfig(AppConfig): def ready(self): from backend.ticket.builders import register_all_builders + from backend.ticket.models import Flow + from backend.ticket.signals import update_ticket_status from backend.ticket.todos import register_all_todos register_all_builders() register_all_todos() post_migrate.connect(init_ticket_flow_config, sender=self) + post_save.connect(update_ticket_status, sender=Flow) diff --git a/dbm-ui/backend/ticket/flow_manager/base.py b/dbm-ui/backend/ticket/flow_manager/base.py index adc4a0980b..1040d612af 100644 --- a/dbm-ui/backend/ticket/flow_manager/base.py +++ b/dbm-ui/backend/ticket/flow_manager/base.py @@ -115,9 +115,6 @@ def run_error_status_handler(self, err: Exception): self.flow_obj.status = TicketFlowStatus.FAILED self.flow_obj.save(update_fields=["err_code", "err_msg", "status", "update_at"]) - self.ticket.status = constants.TicketStatus.FAILED - self.ticket.save(update_fields=["status", "update_at"]) - # 如果是自动重试,则认为flow和ticket都在执行,否则打印异常的堆栈 if err_code == FlowErrCode.AUTO_EXCLUSIVE_ERROR.value: self.run_status_handler(flow_obj_id=self.flow_obj.flow_obj_id) @@ -130,18 +127,12 @@ def run_status_handler(self, flow_obj_id: str): self.flow_obj.status = TicketFlowStatus.RUNNING self.flow_obj.save(update_fields=["flow_obj_id", "status", "update_at"]) - self.ticket.status = constants.TicketStatus.RUNNING - self.ticket.save(update_fields=["status", "update_at"]) - def flush_error_status_handler(self): """重试刷新错误节点,更新相关状态,剔除错误信息""" self.flow_obj.err_msg = self.flow_obj.err_code = None self.flow_obj.status = TicketFlowStatus.RUNNING self.flow_obj.save(update_fields=["err_msg", "status", "err_code", "update_at"]) - self.ticket.status = constants.TicketStatus.RUNNING - self.ticket.save(update_fields=["status", "update_at"]) - def create_operate_records(self, object_key, record_model, object_ids): """ 写入操作记录的通用方法 diff --git a/dbm-ui/backend/ticket/flow_manager/manager.py b/dbm-ui/backend/ticket/flow_manager/manager.py index 8005954c67..15694c879a 100644 --- a/dbm-ui/backend/ticket/flow_manager/manager.py +++ b/dbm-ui/backend/ticket/flow_manager/manager.py @@ -76,8 +76,6 @@ def get_ticket_flow_cls(flow_type): def run_next_flow(self): next_flow = self.ticket.next_flow() - # 更新单据状态,任务失败后也可能被拉起重试,需将单据恢复到执行中到状态 - self.update_ticket_status() if not next_flow: # 没有下一个节点,说明流程已结束 return @@ -88,14 +86,13 @@ def run_next_flow(self): is_init_flow = next_flow.id == self.current_flow_obj.id if is_init_flow or self.current_ticket_flow.status in FLOW_FINISHED_STATUS: self.get_ticket_flow_cls(flow_type=next_flow.flow_type)(next_flow).run() - # 执行后更新单据状态,以保证最新的状态是准确的 - self.update_ticket_status() def update_ticket_status(self): # 获取流程状态集合 statuses = { self.get_ticket_flow_cls(flow_type=flow.flow_type)(flow).status for flow in self.ticket.flows.all() } + logger.info(f"update_ticket_status for ticket:{self.ticket.id}, statuses: {statuses}") if constants.TicketFlowStatus.FAILED in statuses: # 只要存在其中一个失败,则单据状态为失败态 target_status = constants.TicketStatus.FAILED diff --git a/dbm-ui/backend/ticket/signals.py b/dbm-ui/backend/ticket/signals.py new file mode 100644 index 0000000000..d1e07a7550 --- /dev/null +++ b/dbm-ui/backend/ticket/signals.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available. +Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at https://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" +from backend.ticket.flow_manager.manager import TicketFlowManager +from backend.ticket.models import Flow + + +def update_ticket_status(sender, instance: Flow, **kwargs): + """ + 更新 ticket flow 状态的同时,更新单据状态,保证一致性 + """ + if not instance.pk: + return + TicketFlowManager(instance.ticket).update_ticket_status()