diff --git a/apps/backend/subscription/tasks.py b/apps/backend/subscription/tasks.py index 590bbf652..e4b66ab64 100644 --- a/apps/backend/subscription/tasks.py +++ b/apps/backend/subscription/tasks.py @@ -16,7 +16,7 @@ from collections import OrderedDict, defaultdict from copy import deepcopy from functools import wraps -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Set, Union from django.utils.translation import ugettext as _ @@ -710,6 +710,7 @@ def run_subscription_task_and_create_instance( # 如果被删掉的实例在 CMDB 找不到,那么就使用最近一次的 InstanceRecord 的快照数据 not_exist_instance_id = set(instance_not_in_scope) - set(deleted_instance_info) + not_exist_instance_id_set = set() if not_exist_instance_id: records = list( models.SubscriptionInstanceRecord.objects.filter( @@ -718,6 +719,7 @@ def run_subscription_task_and_create_instance( ) for record in records: deleted_instance_info[record.instance_id] = record.instance_info + not_exist_instance_id_set.add(record.instance_id) logger.info( "[sub_lifecycle][run_subscription_task_and_create_instance] " @@ -727,6 +729,46 @@ def run_subscription_task_and_create_instance( not_exist_instance_id, len(records), ) + is_latest_false_instance_ids: Set[str] = not_exist_instance_id - not_exist_instance_id_set + exist_db_instance_id_set = set() + if is_latest_false_instance_ids: + sub_inst_ids_gby_instance_id: Dict[str, List[int]] = defaultdict(list) + max_sub_inst_id_list = [] + subs_inst_records = models.SubscriptionInstanceRecord.objects.filter( + subscription_id=subscription.id, instance_id__in=is_latest_false_instance_ids + ).values("id", "instance_id") + for sub_inst_record_dict in subs_inst_records: + sub_inst_ids_gby_instance_id[sub_inst_record_dict["instance_id"]].append(sub_inst_record_dict["id"]) + exist_db_instance_id_set.add(sub_inst_record_dict["instance_id"]) + + for sub_inst_record_id_list in sub_inst_ids_gby_instance_id.values(): + max_sub_inst_id_list.append(max(sub_inst_record_id_list)) + + subs_inst_records_qs = models.SubscriptionInstanceRecord.objects.filter(id__in=max_sub_inst_id_list).values( + "instance_id", "instance_info" + ) + for sub_inst_record_info in subs_inst_records_qs: + deleted_instance_info[sub_inst_record_info["instance_id"]] = sub_inst_record_info["instance_info"] + + logger.info( + "[sub_lifecycle][run_subscription_task_and_create_instance] " + "deleted instances not exist in cc, find latest record from db -> %s, find num -> %s", + subscription.id, + subscription_task.id, + is_latest_false_instance_ids, + len(subs_inst_records_qs), + ) + + not_exist_db_instance_id_set: Set[str] = is_latest_false_instance_ids - exist_db_instance_id_set + if not_exist_db_instance_id_set: + logger.info( + "[sub_lifecycle][run_subscription_task_and_create_instance] " + "deleted instances not exist in cc, and can't find latest record from db -> %s, num -> %s", + subscription.id, + subscription_task.id, + not_exist_db_instance_id_set, + len(not_exist_db_instance_id_set), + ) instances.update(deleted_instance_info)