2025-03-12 14:17:53 +08:00

288 lines
7.7 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.

#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();
iot_public::StopLogSystem();
}
bool client_cfd::start(int argc, char *argv[], int &nStatus)
{
assert( !m_ptrRedunSw ); //< NULL
iot_public::CSysInfoInterfacePtr ptrSysInfo;
EnRunModel enRunModel = RM_NORMAL;
std::string strAppName = CN_AppName_COMAPP;
//< 启动日志
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;
}
//< 消息总线
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];
}
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;
m_ptrProcMng = iot_sys::getProcMngInstance( objProcInfo );
if ( !m_ptrProcMng )
{
LOGFATAL( "getProcMngInstance return NULL" );
return false;
}
m_ptrProcMng->setCallback( this );
}
//< 冗余管理
{
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 !");
}
//< 停止消息总线
iot_net::releaseMsgBus();
//< 停止日志系统
//移到析构函数中防止日志库停止后又写日志从而使log4cplus提示找不到logger
//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()
{
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;
}
}