|
@@ -0,0 +1,320 @@
|
|
|
+#include "ThreadCompareItemManager.h"
|
|
|
+
|
|
|
+#include "GlobalInfo.h"
|
|
|
+#include "SystemConfig.h"
|
|
|
+#include "CompareItemThread.h"
|
|
|
+#include "ThreadPool.h"
|
|
|
+
|
|
|
+
|
|
|
+ThreadCompareItemManager::ThreadCompareItemManager()
|
|
|
+{
|
|
|
+ m_logger = spdlog::get("CompareItemManager");
|
|
|
+ if(m_logger == nullptr)
|
|
|
+ {
|
|
|
+ fmt::print("ThreadCompareItemManager: CompareItemManager Logger not found.\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+ThreadCompareItemManager::~ThreadCompareItemManager()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/* 线程函数 */
|
|
|
+void ThreadCompareItemManager::thread_CompareItemManager()
|
|
|
+{
|
|
|
+ /* 初始化webapi */
|
|
|
+ m_webAPIUrl = GInfo.webAPIUrl();
|
|
|
+ m_webAPIID = GInfo.webAPIID();
|
|
|
+ m_appType = GInfo.appType();
|
|
|
+ if(m_fromWebAPI.initWebApi(m_webAPIUrl, m_webAPIID, m_appType))
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "ThreadCompareItemManager: 初始化WebAPI失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 创建一些变量 */
|
|
|
+ int threadSleepTime = 2; // 线程休眠时间,单位秒
|
|
|
+ QList<CompareItemInfo_t> listCreateItems; // 新创建的对比项列表
|
|
|
+ QList<CompareItemInfo_t> listUpdateItems; // 更新的对比项列表
|
|
|
+ QList<int> listDeleteItems; // 删除的对比项列表
|
|
|
+
|
|
|
+ /* 获取基础配置,目前只获取一次 */
|
|
|
+ updateBaseSettings();
|
|
|
+
|
|
|
+ SPDLOG_LOGGER_INFO(m_logger, "开启对比项管理线程");
|
|
|
+ while(true)
|
|
|
+ {
|
|
|
+ std::this_thread::sleep_for(std::chrono::seconds(threadSleepTime));
|
|
|
+ if(threadSleepTime < 10)
|
|
|
+ {
|
|
|
+ /* 线程睡眠时间恢复为10秒 */
|
|
|
+ threadSleepTime = 10;
|
|
|
+ }
|
|
|
+ /* ------------------------------ 处理对比项信息 ------------------------------ */
|
|
|
+ if(!m_fromWebAPI.getCompareItemInfo(m_listNewItems))
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_DEBUG(m_logger, "ThreadCompareItemManager: 获取对比项失败");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ listCreateItems.clear();
|
|
|
+ listUpdateItems.clear();
|
|
|
+ listDeleteItems.clear();
|
|
|
+ processCompareItemInfo(listCreateItems, listUpdateItems, listDeleteItems);
|
|
|
+
|
|
|
+ /* 先删除已消失的对比项信息 */
|
|
|
+ processDeleteCompareItemThreads(listDeleteItems);
|
|
|
+ /* 更新需要更新的线程 */
|
|
|
+ updateRunningThreads(listUpdateItems);
|
|
|
+ /* 再创建新的对比项线程 */
|
|
|
+ createNewCompareItemThreads(listCreateItems);
|
|
|
+ }
|
|
|
+
|
|
|
+ SPDLOG_LOGGER_INFO(m_logger, "ThreadCompareItemManager: 线程结束");
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/* 更新基础设置信息,如数据库设置,噪音参数等 */
|
|
|
+bool ThreadCompareItemManager::updateBaseSettings()
|
|
|
+{
|
|
|
+ /* 更新基础数据 */
|
|
|
+ QMap<std::string, std::string> baseSettings;
|
|
|
+ if(!m_fromWebAPI.getSystemConfig(baseSettings))
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "获取系统配置失败");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ /* 将获取到的配置转换成结构体 */
|
|
|
+ for(auto it = baseSettings.begin(); it != baseSettings.end(); ++it)
|
|
|
+ {
|
|
|
+
|
|
|
+ if(Config_Base == it.key())
|
|
|
+ {
|
|
|
+ if(!SysConfig.getBaseConfigFromJson(it.value()))
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("获取基础配置失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(Config_CompareAI == it.key())
|
|
|
+ {
|
|
|
+ if(!SysConfig.getAICompareConfigFromJson(it.value()))
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("获取AI对比配置失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(Config_NoiseBase == it.key())
|
|
|
+ {
|
|
|
+ if(!SysConfig.getNoiseDetectBaseConfigFromJson(it.value()))
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("获取噪音检测基础配置失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(Config_NoiseParam == it.key())
|
|
|
+ {
|
|
|
+ if(!SysConfig.getNoiseDetectParamFromJson(it.value()))
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("获取噪音检测参数失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(Config_Database == it.key())
|
|
|
+ {
|
|
|
+ if(!SysConfig.getDatabaseConfigFromJson(it.value()))
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("获取数据库设置失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ SPDLOG_DEBUG("未知的系统配置项: {}", it.key());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 检测时段单独获取 */
|
|
|
+ QMap<int, DetectPeriodConfig_t> mapDetectConfig;
|
|
|
+ if(!m_fromWebAPI.getDetectPeriodConfig(mapDetectConfig))
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("获取对比项检测时段配置失败");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ SysConfig.setDetectPeriodConfig(mapDetectConfig);
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief 处理对比项信息,新获取的和已有的对比
|
|
|
+ *
|
|
|
+ * @param createList 创建列表
|
|
|
+ * @param updateList 更新列表,根据对比项ID进行更新信息
|
|
|
+ * @param deleteList 删除列表
|
|
|
+ */
|
|
|
+void ThreadCompareItemManager::processCompareItemInfo(QList<CompareItemInfo_t>& createList, QList<CompareItemInfo_t>& updateList, QList<int>& deleteList)
|
|
|
+{
|
|
|
+ QMap<int, CompareItemInfo_t> mapNowItems;
|
|
|
+ /* 先从对比项线程中获取对比项信息 */
|
|
|
+ for(auto it = m_mapThreads.begin(); it != m_mapThreads.end(); ++it)
|
|
|
+ {
|
|
|
+ BaseCalculateThread* pThread = it.value();
|
|
|
+ if(pThread == nullptr)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 获取对比项信息 */
|
|
|
+ CompareItemInfo_t itemInfo = pThread->getThreadInfo().compareItemInfo;
|
|
|
+ mapNowItems.insert(itemInfo.nID, itemInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 遍历新获取的对比项信息,找出需要新增的对比项和需要更新的对比项 */
|
|
|
+ for(const CompareItemInfo_t& item : m_listNewItems)
|
|
|
+ {
|
|
|
+ if(!mapNowItems.contains(item.nID))
|
|
|
+ {
|
|
|
+ /* 新对比项,添加到创建列表 */
|
|
|
+ createList.append(item);
|
|
|
+ } else
|
|
|
+ {
|
|
|
+ /* 已有对比项,检查是否需要更新 */
|
|
|
+ const CompareItemInfo_t& existingItem = mapNowItems.value(item.nID);
|
|
|
+ /* 先对比基础信息 */
|
|
|
+ if(!existingItem.isEqualBase(item))
|
|
|
+ {
|
|
|
+ /* 基础信息不同,需要更新 */
|
|
|
+ updateList.append(item);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ /* 在对比对比项通道信息 */
|
|
|
+ if(!existingItem.isEqualRoads(item))
|
|
|
+ {
|
|
|
+ /* 通道信息不同,需要更新 */
|
|
|
+ updateList.append(item);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* 遍历当前对比项信息,找出需要删除的对比项 */
|
|
|
+ for(auto it : mapNowItems)
|
|
|
+ {
|
|
|
+ for(const CompareItemInfo_t& newItem : m_listNewItems)
|
|
|
+ {
|
|
|
+ if(it.nID == newItem.nID)
|
|
|
+ {
|
|
|
+ break; // 找到对应的对比项,不需要删除
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* 当前对比项不在新获取的对比项中,说明需要删除 */
|
|
|
+ deleteList.append(it.nID);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief 处理需要删除的对比项线程
|
|
|
+ * 1、先处理已经停止的线程
|
|
|
+ * 2、再将这次列表中的对比项ID对应的线程设置为停止状态,待到下次循环再删除已经停止完成的线程
|
|
|
+ *
|
|
|
+ * @param deleteList
|
|
|
+ */
|
|
|
+void ThreadCompareItemManager::processDeleteCompareItemThreads(const QList<int>& deleteList)
|
|
|
+{
|
|
|
+ /* 先处理已经停止运行的线程 */
|
|
|
+ for(auto it = m_mapThreads.begin(); it != m_mapThreads.end();)
|
|
|
+ {
|
|
|
+ BaseCalculateThread* pThread = it.value();
|
|
|
+ if(pThread == nullptr)
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_WARN(m_logger, "对比项线程指针为空,即将删除该线程指针");
|
|
|
+ it = m_mapThreads.erase(it);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if(pThread->getThreadInfo().threadState == EThreadState::State_Stopped)
|
|
|
+ {
|
|
|
+ /* 线程已经停止,直接删除 */
|
|
|
+ SPDLOG_LOGGER_INFO(m_logger, "对比项线程 {} 已经停止,准备删除", pThread->getThreadInfo().compareItemInfo.strName.toStdString());
|
|
|
+ delete pThread;
|
|
|
+ it = m_mapThreads.erase(it);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ ++it;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 停止本次需要停止的线程 */
|
|
|
+ for(auto it : m_mapThreads)
|
|
|
+ {
|
|
|
+ int compareItemID = it->getThreadInfo().compareItemInfo.nID;
|
|
|
+ if(deleteList.contains(compareItemID))
|
|
|
+ {
|
|
|
+ /* 设置线程停止标志 */
|
|
|
+ it->stopThread();
|
|
|
+ SPDLOG_LOGGER_INFO(m_logger, "对比项线程 {} 设置为停止状态", it->getThreadInfo().compareItemInfo.strName.toStdString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 更新正在运行的线程信息 */
|
|
|
+void ThreadCompareItemManager::updateRunningThreads(const QList<CompareItemInfo_t>& updateList)
|
|
|
+{
|
|
|
+ if(updateList.isEmpty())
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for(const CompareItemInfo_t& item : updateList)
|
|
|
+ {
|
|
|
+ auto it = m_mapThreads.find(item.nID);
|
|
|
+ if(it == m_mapThreads.end())
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_WARN(m_logger, "对比项线程 {} 不存在,无法更新信息", item.strName.toStdString());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ BaseCalculateThread* pThread = it.value();
|
|
|
+ if(pThread == nullptr)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ CalculateThreadInfo_t threadInfo;
|
|
|
+ threadInfo.compareItemInfo = item;
|
|
|
+ pThread->updateThreadInfo(threadInfo);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 创建新的线程 */
|
|
|
+bool ThreadCompareItemManager::createNewCompareItemThreads(const QList<CompareItemInfo_t>& createList)
|
|
|
+{
|
|
|
+ if(createList.isEmpty())
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_DEBUG(m_logger, "没有新的对比项需要创建");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ for(auto& it : createList)
|
|
|
+ {
|
|
|
+ /* 创建新的对比项线程 */
|
|
|
+ CalculateThreadInfo_t threadInfo;
|
|
|
+ threadInfo.compareItemInfo = it;
|
|
|
+ threadInfo.threadType = EThreadType::Type_CompareItem;
|
|
|
+ threadInfo.threadState = EThreadState::State_Inited;
|
|
|
+
|
|
|
+ /* 创建线程对象 */
|
|
|
+ BaseCalculateThread* pThread = new CompareItemThread(threadInfo);
|
|
|
+ if(pThread == nullptr)
|
|
|
+ {
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "创建对比项线程 {} 失败", it.strName.toStdString());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 启动线程 */
|
|
|
+ CPPTP.add_task(&CompareItemThread::threadTask, pThread);
|
|
|
+
|
|
|
+ /* 添加到线程列表中 */
|
|
|
+ m_mapThreads.insert(it.nID, pThread);
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|