288 lines
7.7 KiB
C++
Raw Normal View History

#include "Client_cfd.h"
#include "pub_sysinfo_api/SysInfoApi.h"
#include "pub_utility_api/SingleProcInstance.h"
#include "boost/program_options.hpp"
namespace cfd_Server{
client_cfd::client_cfd()
{
p_manger = NULL;
}
client_cfd::~client_cfd()
{
stop();
2025-03-12 14:17:53 +08:00
iot_public::StopLogSystem();
}
bool client_cfd::start(int argc, char *argv[], int &nStatus)
{
assert( !m_ptrRedunSw ); //< NULL
2025-03-12 14:17:53 +08:00
iot_public::CSysInfoInterfacePtr ptrSysInfo;
EnRunModel enRunModel = RM_NORMAL;
std::string strAppName = CN_AppName_COMAPP;
//< 启动日志
2025-03-12 14:17:53 +08:00
iot_public::StartLogSystem( strAppName.c_str(), EZ_NYGK_PROC_NAME );
if ( iot_public::createSysInfoInstance(ptrSysInfo) == false )
{
LOGFATAL( "createSysInfoInstance() return false !" );
return false;
}
//< 获取运行参数
if ( kbdSuccess != ptrSysInfo->getLocalRunAppInfoByName(strAppName,m_stRunAppInfo))
{
LOGFATAL( "getLocalRunAppInfoByName() failed !" );
return false;
}
//< 参数解析
if ( !parseCommandLine( argc, argv, enRunModel, strAppName ))
{
// help返回的也是false输出失败不合适
//std::cerr << "参数解析失败" << std::endl;
return false;
}
//< 判断是否已启动
if ( isAlreadyRunning())
{
LOGFATAL( EZ_NYGK_PROC_NAME" 已启动,不可重复启动,本实例退出!" );
return false;
}
//< 消息总线
2025-03-12 14:17:53 +08:00
if ( !iot_net::initMsgBus( EZ_NYGK_PROC_NAME, "", true ))
{
LOGFATAL( "消息总线初始化失败,程序启动失败!" );
return false;
}
//业务初始化
p_manger = new client_MsgManger;
p_manger->resume();
m_ptrRedunSw = boost::make_shared<CWebSrvRedunSw>( this );
switch ( enRunModel )
{
case RM_NORMAL:
{
//< 进程管理
{
std::string strStartArgs;
for ( int i = 1; i < argc; ++i )
{
if ( i != 1 )
{
strStartArgs += " ";
}
strStartArgs += argv[i];
}
2025-03-12 14:17:53 +08:00
iot_sys::SProcessInfoKey objProcInfo;
objProcInfo.nAppId = m_stRunAppInfo.nAppId;
objProcInfo.nDomainId = m_stRunAppInfo.nDomainId;
objProcInfo.strNodeName = m_stRunAppInfo.strLocalNodeName;
objProcInfo.strProcName = EZ_NYGK_PROC_NAME;
objProcInfo.strProcParam = strStartArgs;
2025-03-12 14:17:53 +08:00
m_ptrProcMng = iot_sys::getProcMngInstance( objProcInfo );
if ( !m_ptrProcMng )
{
LOGFATAL( "getProcMngInstance return NULL" );
return false;
}
m_ptrProcMng->setCallback( this );
}
//< 冗余管理
{
2025-03-12 14:17:53 +08:00
m_ptrRedundantMng = iot_sys::getRedundantMngInstance( m_stRunAppInfo.nDomainId,
m_stRunAppInfo.nAppId,
m_stRunAppInfo.strLocalNodeName );
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 ( kbdSuccess != m_ptrRedunSw->redundantSwitch( true, false ))
{
LOGFATAL( "以主机模式启动失败!" );
return false;
}
}
break;
case RM_NO_PROC_MNG_SLAVE:
{
if ( kbdSuccess != m_ptrRedunSw->redundantSwitch( false, true ))
{
LOGFATAL( "以备机模式启动失败!" );
return false;
}
}
break;
default:
{
LOGFATAL( "非预期的启动模式,程序启动失败!" );
return false;
}
break;
}
LOGINFO( EZ_NYGK_PROC_NAME" is now running ..." );
return true;
}
bool client_cfd::stop()
{
LOGINFO( EZ_NYGK_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(p_manger != NULL){
p_manger->quit();
delete p_manger;
p_manger = NULL;
}
//< 更新进程管理状态
if ( m_ptrProcMng )
{
LOGDEBUG("Release m_ptrProcMng ...");
updateProcInfo( false, false, false );
m_ptrProcMng.reset();
LOGDEBUG("Release m_ptrProcMng complete !");
}
//< 停止消息总线
2025-03-12 14:17:53 +08:00
iot_net::releaseMsgBus();
//< 停止日志系统
//移到析构函数中防止日志库停止后又写日志从而使log4cplus提示找不到logger
2025-03-12 14:17:53 +08:00
//iot_public::StopLogSystem();
return true;
}
int client_cfd::toQuit()
{
shutdown();
return kbdSuccess;
}
int client_cfd::updateProcInfo(bool bActive, bool bMaster, bool bSlave)
{
if ( m_ptrProcMng )
{
return m_ptrProcMng->updateProcessInfo( bActive, bMaster, bSlave );
}
return kbdFailed;
}
bool client_cfd::isAlreadyRunning()
{
2025-03-12 14:17:53 +08:00
return iot_public::CSingleProcInstance::hasInstanceRunning( EZ_NYGK_PROC_NAME );
}
bool client_cfd::parseCommandLine( int argc, char *argv[], EnRunModel &enRunModel, std::string &strAppName )
{
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" )
( "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" ))
{
strAppName = vm["app"].as<std::string>();
}
else
{
strAppName = CN_AppName_COMAPP;
}
if ( vm.count( "no_proc_mng_master" ))
{
enRunModel = RM_NO_PROC_MNG_MASTER;
}
else if ( vm.count( "no_proc_mng_slave" ))
{
enRunModel = RM_NO_PROC_MNG_SLAVE;
}
else
{
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;
}
}