修复:删除算法绑定后边缘端未停止对应算法推理
根本原因:config_sync.py 的 _cleanup_stale_records() 方法接收了 incoming_bind_ids 参数但从未使用,导致当 ROI 仍存在但其中某个 算法绑定被删除时,孤立的绑定记录继续留在 SQLite 中,推理循环 仍然从 SQLite 读取到已删除的绑定并继续生成告警。 修复内容: 1. config/database.py: 添加 get_all_bind_ids() 方法 2. core/config_sync.py: 在 _cleanup_stale_records() 中补全 使用 incoming_bind_ids 清理孤立绑定的逻辑 3. algorithms.py: 在 reload_all_algorithms() 中添加清理内存中 孤立算法实例的逻辑,防止内存泄漏
This commit is contained in:
@@ -998,9 +998,13 @@ class AlgorithmManager:
|
||||
config_manager = get_config_sync_manager()
|
||||
bindings = config_manager.get_bindings_from_redis("")
|
||||
|
||||
# 收集当前配置中有效的 (roi_id, bind_id) 组合
|
||||
valid_keys = set()
|
||||
|
||||
for bind in bindings:
|
||||
bind_id = bind.get("bind_id")
|
||||
roi_id = bind.get("roi_id")
|
||||
valid_keys.add((roi_id, bind_id))
|
||||
|
||||
if preserve_state:
|
||||
# 仅更新参数,不重置状态
|
||||
@@ -1012,6 +1016,32 @@ class AlgorithmManager:
|
||||
if self.load_bind_from_redis(bind_id):
|
||||
count += 1
|
||||
|
||||
# 清理内存中已被删除的算法实例
|
||||
removed_count = 0
|
||||
with self._update_lock:
|
||||
for roi_id in list(self.algorithms.keys()):
|
||||
for key in list(self.algorithms[roi_id].keys()):
|
||||
# key 格式: "roi_id_bind_id"
|
||||
if key.startswith(roi_id + "_"):
|
||||
bind_id = key[len(roi_id) + 1:]
|
||||
if (roi_id, bind_id) not in valid_keys:
|
||||
for algo in self.algorithms[roi_id][key].values():
|
||||
algo.reset()
|
||||
del self.algorithms[roi_id][key]
|
||||
# 清除注册缓存
|
||||
self._registered_keys = {
|
||||
k for k in self._registered_keys
|
||||
if not (k[0] == roi_id and k[1] == bind_id)
|
||||
}
|
||||
removed_count += 1
|
||||
logger.info(f"清理已删除的算法实例: {key}")
|
||||
# 如果 roi 下已无算法实例,清理空字典
|
||||
if not self.algorithms[roi_id]:
|
||||
del self.algorithms[roi_id]
|
||||
|
||||
if removed_count > 0:
|
||||
logger.info(f"已清理 {removed_count} 个孤立算法实例")
|
||||
|
||||
logger.info(f"已重新加载 {count} 个算法配置 (preserve_state={preserve_state})")
|
||||
return count
|
||||
except Exception as e:
|
||||
|
||||
@@ -899,7 +899,17 @@ class SQLiteManager:
|
||||
except Exception as e:
|
||||
logger.error(f"删除ROI算法绑定失败: {e}")
|
||||
return 0
|
||||
|
||||
|
||||
def get_all_bind_ids(self) -> List[str]:
|
||||
"""获取所有算法绑定的 bind_id 列表(用于清理孤立绑定)"""
|
||||
try:
|
||||
cursor = self._conn.cursor()
|
||||
cursor.execute("SELECT bind_id FROM roi_algo_bind")
|
||||
return [row[0] for row in cursor.fetchall()]
|
||||
except Exception as e:
|
||||
logger.error(f"获取所有绑定ID失败: {e}")
|
||||
return []
|
||||
|
||||
def log_config_update(
|
||||
self,
|
||||
config_type: str,
|
||||
|
||||
@@ -640,6 +640,15 @@ class ConfigSyncManager:
|
||||
removed += 1 + bind_count
|
||||
logger.info(f"清理旧 ROI: {old_roi_id} (含 {bind_count} 条算法绑定)")
|
||||
|
||||
# 清理孤立的算法绑定(ROI 仍存在但绑定已被删除的情况)
|
||||
if incoming_bind_ids:
|
||||
existing_bind_ids = self._db_manager.get_all_bind_ids()
|
||||
for old_bind_id in existing_bind_ids:
|
||||
if old_bind_id not in incoming_bind_ids:
|
||||
self._db_manager.delete_roi_algo_bind(old_bind_id)
|
||||
removed += 1
|
||||
logger.info(f"清理孤立算法绑定: {old_bind_id}")
|
||||
|
||||
if removed > 0:
|
||||
logger.info(f"旧数据清理完成: 共删除 {removed} 条过期记录")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user