#include "pub_logger_api/logger.h" #include "boost/thread.hpp" #include "boost/lexical_cast.hpp" #include "pub_utility_api/TimeUtil.h" #include "CMethodSeq.h" #include "CNodeSeq.h" #include "CNodeIterator.h" #include "CMethodFunc.h" #include "CDbSaveCtrl.h" #include "CModuleDbAccessMngr.h" #include "CRecoverNode.h" #include "CModuleAlarmCreater.h" CMethodSeq::CMethodSeq(CNodeSeq& seq) :m_objSeq(seq) { m_objSeq.setMethod(this); } CMethodSeq::~CMethodSeq() { CMethodSeq::interruptExecute(); m_objSeq.setMethod(NULL); } bool CMethodSeq::execute() { LOGINFO("顺控:[%s] 开始执行!", m_objSeq.description().c_str() ); m_objSeq.setStartTime(kbd_public::getUTCTimeSec()); addSeqHistory(); bool bRet = executeChilds(); LOGINFO("顺控:[%s] 结束执行 状态[%s]!", m_objSeq.description().c_str(), (bRet ? ("成功") : ("失败")) ); updateSeqHistory(); return bRet; } void CMethodSeq::interruptExecute() { std::vector::iterator iter = m_vecAsyncThreads.begin(); for (; iter != m_vecAsyncThreads.end(); ++iter) { (*iter)->interruptExecuter(); delete *iter; *iter = NULL; } m_vecAsyncThreads.clear(); } bool CMethodSeq::executeChilds() { //将状态 设置为 正在执行 changeStateToStart(); m_objSeq.getAlarmCreater().seqStart(m_objSeq); //开始处理所有功能, 返回的 列表是 并行功能的队列 ESeqCtrl_NodeState resultState = startExecuteChilds(m_vecAsyncThreads); //处理并行功能的结果 ESeqCtrl_NodeState resultAsyncState = startAsyncExecuteChilds(m_vecAsyncThreads); //计算出整个顺控的状态 resultState = getAsyncResultState(resultState, resultAsyncState); switch (resultState) { case SEQ_FAILED_STATUS: changeStateToFailed(); break; case SEQ_SUCCESS_STATUS: changeStateToSuccess(); break; case SEQ_STOP_STATUS: changeStateToStop(); break; default: BOOST_ASSERT(false); break; } //clearAsyncVec(m_vecAsyncThreads); m_objSeq.getAlarmCreater().seqStop(m_objSeq); return resultState == SEQ_SUCCESS_STATUS; } ESeqCtrl_NodeState CMethodSeq::startExecuteChilds( std::vector& vec) { ESeqCtrl_NodeState resultState = SEQ_SUCCESS_STATUS; //遍历子节点 CNodeFuncIterator iter(m_objSeq); while (iter.hasNext()) { CNodeFunc& func = iter.getNext(); resultState = doOneFunc(func, vec); if (resultState != SEQ_SUCCESS_STATUS) { break; } } return resultState; } ESeqCtrl_NodeState CMethodSeq::startAsyncExecuteChilds(std::vector& vec) { ESeqCtrl_NodeState resultState = SEQ_SUCCESS_STATUS; //等待并行结束,并行的功能 , //并行功能如果执行失败了,并不会影响整个顺控的执行, //整个顺控的的成功和失败 是 会在所有功能都结束后判断的 bool bAsyncResult = true; std::vector::iterator iterVecAsync = vec.begin(); for (; iterVecAsync != vec.end(); ++iterVecAsync) { bAsyncResult = (*iterVecAsync)->waitExecuteEnd(); if (!bAsyncResult) { CNodeFunc& func = (*iterVecAsync)->getFuncNode(); resultState = getAsyncResultState(resultState, func.getState()); } } return resultState; } ESeqCtrl_NodeState CMethodSeq::doOneFunc( CNodeFunc& func, std::vector& vec) { //如果没有勾选,则不用执行 if (func.checkStatus() == CNode::NODE_CHECK_STATUS_UNCHECK) { return SEQ_SUCCESS_STATUS; } //并行,创建异步 存在异步队列中 if ((!m_objSeq.isSecExe()) && func.isAsync()) { doOneAsysncFunc(func, vec); return SEQ_SUCCESS_STATUS; } return doOneSysncFunc(func); } ESeqCtrl_NodeState CMethodSeq::doOneSysncFunc(CNodeFunc& func) { //串行 CMethodFunc funcMethod(func); funcMethod.execute(); return func.getState(); } ESeqCtrl_NodeState CMethodSeq::doOneAsysncFunc(CNodeFunc& func, std::vector& vec) { CMethodFuncAsync* pAsyncPro = new CMethodFuncAsync(func); vec.push_back(pAsyncPro); //并行的执行失败了,只能等待串行结束后再做处理 return SEQ_SUCCESS_STATUS; } void CMethodSeq::clearAsyncVec(std::vector& vec) { std::vector::iterator iter = vec.begin(); for (; iter != vec.end(); ++iter) { delete *iter; *iter = NULL; } vec.clear(); } void CMethodSeq::notifyStateToHmi() { CMbCommunicateInfo& mb = m_objSeq.getMbCmmInfo(); mb.nodeStatusToHmi(m_objSeq); } void CMethodSeq::changeStateToStart() { m_objSeq.updateState(SEQ_RUNNING_STATUS); updateSeqRunning(false); notifyStateToHmi(); } void CMethodSeq::changeStateToSuccess() { m_objSeq.updateState(SEQ_SUCCESS_STATUS); updateSeqRunning(); notifyStateToHmi(); } void CMethodSeq::changeStateToFailed() { m_objSeq.updateState(SEQ_FAILED_STATUS); updateSeqRunning(); notifyStateToHmi(); } void CMethodSeq::changeStateToStop() { m_objSeq.updateState(SEQ_STOP_STATUS); updateSeqRunning(); notifyStateToHmi(); } void CMethodSeq::changeStateToPause() { m_objSeq.updateState(SEQ_PAUSE_STATUS); updateSeqRunning(); notifyStateToHmi(); } bool CMethodSeq::updateSeqRunning(bool onlyState) { SSeqCtrlRunning info; memset(&info, 0, sizeof(info)); SNodeSeqActor actor = m_objSeq.getSeqActor(); strcpy(info.seq_name, m_objSeq.nodeName().c_str()); strcpy(info.node_desc, m_objSeq.description().c_str()); info.action_no = 0; info.func_no = 0; info.node_type = 0; info.status = m_objSeq.getState(); info.checked = m_objSeq.checkStatus(); info.start_time = m_objSeq.getStartTime(); info.user_id = actor.user_id; info.user_groupid = actor.user_grounp_id; strcpy(info.host_name, actor.host_name.c_str()); strcpy(info.user_name, actor.user_name.c_str()); info.timeflag = m_objSeq.timeFlag(); info.relation = 0; info.delay_time = 0; info.fail_strage = 0; info.isses = m_objSeq.isSecExe(); //strcpy(info.key_id_tag, m_ptrAction->keyIdTag().c_str()); info.targetvalue = 0; info.location_id = m_objSeq.locationId(); info.seq_type = m_objSeq.seqType(); CModuleDbAccessMngr& access = m_objSeq.getDbAccess(); return access.updateSeqRunningRecord(info, onlyState); } ESeqCtrl_NodeState CMethodSeq::getAsyncResultState( ESeqCtrl_NodeState oldState, ESeqCtrl_NodeState newState) { //失败优先级最高,一旦失败,就是失败 if (newState == SEQ_FAILED_STATUS || oldState == SEQ_FAILED_STATUS) { return SEQ_FAILED_STATUS; } //终止状态 if (newState == SEQ_STOP_STATUS || oldState == SEQ_STOP_STATUS) { return SEQ_STOP_STATUS; } if (newState == SEQ_SUCCESS_STATUS && oldState == SEQ_SUCCESS_STATUS) { return SEQ_SUCCESS_STATUS; } return newState; } bool CMethodSeq::updateSeqHistory() { CDbSaveCtrl db; SSeqHistory info; info.seq_name = m_objSeq.nodeName(); info.seq_desc = m_objSeq.description(); info.time = m_objSeq.getStartTime();//开始执行的时间 info.status = CNode::getStateStr(m_objSeq.getState()); info.location_id = m_objSeq.locationId(); SNodeSeqActor actor = m_objSeq.getSeqActor(); info.user_id = actor.user_id; info.user_group = actor.user_grounp_id; info.host_name = actor.host_name; info.user_name = actor.user_name; info.seq_type = m_objSeq.seqType(); bool bRet = db.updateSeqHistory(info); return bRet; } //添加历史表,需要把功能 和 动作的一并写入 bool CMethodSeq::addSeqHistory() { CDbSaveCtrl db; SSeqHistory seqInfo; SSeqFunctionHistory funcInfo; SSeqCtrlActionEvent actionInfo; bool bRet = true; CNodeFuncIterator funcIter(m_objSeq); while (bRet && funcIter.hasNext()) { CNodeFunc& func = funcIter.getNext(); CNodeActionIterator actionIter(func); while (bRet && actionIter.hasNext()) { CNodeAction& action = actionIter.getNext(); actionInfo.seq_name = m_objSeq.nodeName(); actionInfo.time = m_objSeq.getStartTime();//执行时间 BOOST_ASSERT(actionInfo.time != 0); actionInfo.func_name = func.nodeName(); actionInfo.action_no = action.actionNo(); actionInfo.action_name = action.nodeName(); actionInfo.action_desc = action.description(); actionInfo.status = CNode::getStateStr(action.getState()); actionInfo.starttime = 0; actionInfo.stoptime = 0; actionInfo.key_id_tag = action.keyIdTag(); actionInfo.targetvalue = action.targetValue(); actionInfo.location_id = action.locationId(); actionInfo.discribe = ""; bRet = db.addActionEvent(actionInfo); } if (!bRet) { break; } funcInfo.seq_name = m_objSeq.nodeName(); funcInfo.time = m_objSeq.getStartTime();//开始执行的时间 funcInfo.func_name = func.nodeName(); funcInfo.func_desc = func.description(); funcInfo.func_no = func.funcNo(); funcInfo.relation = func.relation(); funcInfo.status = CNode::getStateStr(func.getState()); funcInfo.location_id = m_objSeq.locationId(); bRet = db.addSeqFuncHistory(funcInfo); } if (bRet) { seqInfo.seq_name = m_objSeq.nodeName(); seqInfo.seq_desc = m_objSeq.description(); seqInfo.time = m_objSeq.getStartTime();//开始执行的时间 seqInfo.status = CNode::getStateStr(SEQ_RUNNING_STATUS); seqInfo.location_id = m_objSeq.locationId(); SNodeSeqActor actor = m_objSeq.getSeqActor(); seqInfo.user_id = actor.user_id; seqInfo.user_group = actor.user_grounp_id; seqInfo.host_name = actor.host_name; seqInfo.user_name = actor.user_name; seqInfo.seq_type = m_objSeq.seqType(); bRet = db.addSeqHistory(seqInfo); } return bRet; }