373 lines
9.5 KiB
C++
373 lines
9.5 KiB
C++
|
|
|
|||
|
|
/******************************************************************************//**
|
|||
|
|
* @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
|
|||
|
|
|