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
|
||
|