2025-03-13 10:46:26 +08:00

373 lines
9.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************//**
* @file CTsdbSaveSrv.cpp
* @brief 时序库存库服务,,服务框架
* @author yikenan
* @version 1.0
* @date
**********************************************************************************/
#include "boost/program_options.hpp"
#include "boost/algorithm/string/predicate.hpp"
#include "pub_logger_api/logger.h"
#include "pub_utility_api/SingleProcInstance.h"
#include "net_msg_bus_api/MsgBusApi.h"
#include "tsdb_api/TsdbApi.h"
#include "CNodeMng.h"
#include "CTsdbSaveSrv.h"
#define TSDB_LOCAL_SAVE_SRV_PROC_NAME "tsdb_local_save"
using namespace std;
using namespace iot_public;
namespace iot_dbms
{
CTsdbSaveSrv::CTsdbSaveSrv()
{
m_enRunModel = RM_NORMAL;
}
CTsdbSaveSrv::~CTsdbSaveSrv()
{
stop();
iot_public::StopLogSystem();
}
//< @param int & nStatus 错误码
bool CTsdbSaveSrv::start(int argc, char *argv[], int& /*nStatus*/)
{
assert(!m_ptrRedunSw); //< NULL
string strAppName;
string strStartArgs;
//< 参数解析
if (!parseCommandLine(argc, argv, strAppName,strStartArgs))
{
std::cerr << "参数解析失败" << std::endl;
return false;
}
//< 启动日志
iot_public::StartLogSystem(strAppName.c_str(), TSDB_LOCAL_SAVE_SRV_PROC_NAME);
if(!getSysAppInfo(strAppName))
{
LOGERROR("获取应用信息失败");
return false;
}
//< 判断是否已启动
if (isAlreadyRunning(strStartArgs))
{
LOGFATAL(TSDB_LOCAL_SAVE_SRV_PROC_NAME" 已启动,不可重复启动,本实例退出!");
return false;
}
//< 消息总线
if (!iot_net::initMsgBus(TSDB_LOCAL_SAVE_SRV_PROC_NAME, "", true))
{
LOGFATAL("初始化消息总线失败,程序启动失败!");
return false;
}
//< 时序库接口库
if (!initTsdbApi())
{
LOGFATAL("初始化时序库接口库失败,程序启动失败!");
return false;
}
//< 初始化 CNodeMng 加载配置等
if (!CNodeMng::getInstance().init(m_stRunAppInfo))
{
LOGFATAL("CNodeMng 初始化失败,程序启动失败!");
return false;
}
//< CFrontThread 由 m_ptrRedunSw 管理
//< 初始化 m_ptrRedunSw
m_ptrRedunSw.reset(new CTsdbSaveRedunSw(this,m_stRunAppInfo));
if(m_ptrRedunSw == NULL || m_ptrRedunSw->initialize() != iotSuccess)
{
LOGFATAL("CNodeMng 初始化失败,程序启动失败!");
return false;
}
switch (m_enRunModel)
{
case RM_NORMAL:
{
//< 进程管理
{
iot_sys::SProcessInfoKey objProcInfo;
objProcInfo.nAppId = m_stRunAppInfo.nAppId;
objProcInfo.nDomainId = CNodeMng::getInstance().getLocalDomainID();
objProcInfo.strNodeName = CNodeMng::getInstance().getLocalNodeName();
objProcInfo.strProcName = TSDB_LOCAL_SAVE_SRV_PROC_NAME;
objProcInfo.strProcParam = strStartArgs;
m_ptrProcMng = iot_sys::getProcMngInstance(objProcInfo);
if (!m_ptrProcMng)
{
LOGFATAL("getProcMngInstance return NULL");
return false;
}
m_ptrProcMng->setCallback(this);
}
//< 冗余管理
{
m_ptrRedundantMng = iot_sys::getRedundantMngInstance(CNodeMng::getInstance().getLocalDomainID(),
m_stRunAppInfo.nAppId,
CNodeMng::getInstance().getLocalNodeName());
if (!m_ptrRedundantMng)
{
LOGERROR("getRedundantMngInstance return NULL");
return false;
}
m_ptrRedundantMng->setCallback(m_ptrRedunSw);
}
//< 更新进程管理状态
updateProcInfo(true, false, false);
}
break;
case RM_NO_PROC_MNG_MASTER:
{
if (iotSuccess != m_ptrRedunSw->redundantSwitch(true, false))
{
LOGFATAL("以主机模式启动失败!");
return false;
}
}
break;
case RM_NO_PROC_MNG_SLAVE:
{
if (iotSuccess != m_ptrRedunSw->redundantSwitch(false, true))
{
LOGFATAL("以备机模式启动失败!");
return false;
}
}
break;
default:
{
LOGFATAL("非预期的启动模式,程序启动失败!");
return false;
}
break;
}
LOGINFO(TSDB_LOCAL_SAVE_SRV_PROC_NAME" is now running ...");
return true;
}
bool CTsdbSaveSrv::stop()
{
LOGINFO(TSDB_LOCAL_SAVE_SRV_PROC_NAME" is now exiting ...");
//< 取消冗余切换,防止正在退出时发生冗余切换
if (m_ptrRedundantMng)
{
//LOGDEBUG("Release m_ptrRedundantMng ...");
m_ptrRedundantMng->unsetCallback();
m_ptrRedundantMng.reset();
//LOGDEBUG("Release m_ptrRedundantMng complete !");
}
//< 释放 m_ptrRedunSw
if (m_ptrRedunSw)
{
//LOGDEBUG("Release m_ptrRedunSw ...");
m_ptrRedunSw.reset();
//LOGDEBUG("Release m_ptrRedunSw complete !");
}
//< 取消进程管理回调
//if (m_ptrProcMng)
//{
// m_ptrProcMng->unsetCallback();
//}
//< 清理业务线程
if (CNodeMng::haveInstance())
{
//LOGDEBUG("Release CNodeMng ...");
//< CFrontThread 由 m_ptrRedunSw 管理
CNodeMng::getInstance().release();
//LOGDEBUG("Release CNodeMng complete !");
}
//< 更新进程管理状态
if (m_ptrProcMng)
{
//LOGDEBUG("Release m_ptrProcMng ...");
updateProcInfo(false, false, false);
m_ptrProcMng.reset();
//LOGDEBUG("Release m_ptrProcMng complete !");
}
//< 释放时序库接口库
releaseTsdbApi();
//< 停止消息总线
iot_net::releaseMsgBus();
//< 停止日志系统
//< 移到析构函数中防止日志库停止后又写日志从而使log4cplus提示找不到logger
//iot_public::StopLogSystem();
return true;
}
int CTsdbSaveSrv::toQuit()
{
shutdown();
return iotSuccess;
}
int CTsdbSaveSrv::updateProcInfo(bool bActive, bool bMaster, bool bSlave)
{
if (m_ptrProcMng)
{
return m_ptrProcMng->updateProcessInfo(bActive, bMaster, bSlave);
}
return iotFailed;
}
bool CTsdbSaveSrv::isAlreadyRunning(const std::string &strStartArgs )
{
std::string strUniqueName = TSDB_LOCAL_SAVE_SRV_PROC_NAME;
strUniqueName += strStartArgs;
return iot_public::CSingleProcInstance::hasInstanceRunning( strUniqueName );
}
bool CTsdbSaveSrv::parseCommandLine(int argc, char *argv[],std::string &strAppName, std::string &strStartArgs)
{
//< 拼接启动参数,用于向进程管理注册
for ( int i = 1; i < argc; ++i )
{
if ( i != 1 )
{
strStartArgs += " ";
}
strStartArgs += argv[i];
}
namespace po = boost::program_options;
po::options_description desc("usage");
po::variables_map vm;
try
{
desc.add_options()
("app"",a", po::value<std::string>(), "\t""The APP name, can only ran as PUBLIC")
("no_proc_mng_master"",m", "\t""Run as master without ProcMng and RedundantMng")
("no_proc_mng_slave"",s", "\t""Run as slave without ProcMng and RedundantMng")
("help"",h", "\t""Print this info");
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help"))
{
std::cout << desc << std::endl;
return false;
}
if (vm.count("no_proc_mng_master") && vm.count("no_proc_mng_slave"))
{
std::cout << "no_proc_mng_master and no_proc_mng_slave can not use at the same time !" << std::endl;
return false;
}
if (0 == vm.count("app"))
{
std::cout << "Must set app !" << std::endl;
return false;
}
else
{
strAppName = vm["app"].as<std::string>();
}
if (vm.count("no_proc_mng_master"))
{
m_enRunModel = RM_NO_PROC_MNG_MASTER;
}
else if (vm.count("no_proc_mng_slave"))
{
m_enRunModel = RM_NO_PROC_MNG_SLAVE;
}
else
{
m_enRunModel = RM_NORMAL;
}
}
catch (std::exception &ex)
{
std::cerr << ex.what() << std::endl;
std::cout << desc << std::endl;
return false;
}
catch (...)
{
std::cerr << "未知错误" << std::endl;
std::cout << desc << std::endl;
return false;
}
return true;
}
bool CTsdbSaveSrv::getSysAppInfo(const std::string &strAppName)
{
CSysInfoInterfacePtr sysInfoPtr;
if(createSysInfoInstance(sysInfoPtr) == false)
{
LOGERROR("AppName=%s ,createSysInfoInstance fail!\n", strAppName.c_str());
return false;
}
if(sysInfoPtr == NULL)
{
LOGERROR("AppName=%s ,Get System Info fail!\n", strAppName.c_str());
return false;
}
if(iotSuccess != sysInfoPtr->getLocalRunAppInfoByName(strAppName,m_stRunAppInfo))
{
LOGERROR("getLocalRunAppInfoByName fail");
return false;
}
return true;
}
} //< namespace iot_dbms