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

268 lines
5.9 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 "boost/program_options.hpp"
#include "pub_sysinfo_api/SysInfoApi.h"
#include "pub_utility_api/SingleProcInstance.h"
#include "pub_logger_api/logger.h"
#include "pub_utility_api/I18N.h"
#include "net/net_msg_bus_api/MsgBusApi.h"
#include "common/Common.h"
#include "CSeqCtrlService.h"
#include "PredifineForSeqServer.h"
#include "CDbSaveCtrl.h"
#define OPT_DESC_APP "app"
#define OPT_DESC_AUTO_MASTER "master"
#define OPT_DESC_HELP "help"
CSeqCtrlService::CSeqCtrlService()
{
}
CSeqCtrlService::~CSeqCtrlService()
{
if (m_ptrTestThread)
{
m_ptrTestThread->interrupt();
m_ptrTestThread->join();
}
CSeqCtrlService::stop();
}
bool CSeqCtrlService::parseCommandLine(int argc,
char *argv[],
std::string& appName,
bool& isMaster)
{
m_strStartArgs = "";
for (int i = 1; i < argc; ++i)
{
if (i != 1)
{
m_strStartArgs += " ";
}
m_strStartArgs += argv[i];
}
namespace po = boost::program_options;
po::options_description desc("usage");
po::variables_map vm;
try
{
desc.add_options()
(OPT_DESC_APP",a", po::value<std::string>(), "app name")
(OPT_DESC_AUTO_MASTER",m", po::value<bool>(), "master(true?false)")
(OPT_DESC_HELP",h", "\thelp");
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count(OPT_DESC_HELP))
{
std::cout << desc << std::endl;
LOGWARN("以帮助参数启动!");
return false;
}
if (vm.count(OPT_DESC_AUTO_MASTER) != 0)
{
isMaster = vm[OPT_DESC_AUTO_MASTER].as<bool>();
}
else
{
isMaster = false;
}
if (vm.count(OPT_DESC_APP) == 0)
{
appName = "base";
LOGWARN("没有输入启动参数使用默认参数base!");
}
else
{
appName = vm[OPT_DESC_APP].as<std::string>();
}
}
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;
LOGERROR("未知错误!");
return false;
}
std::cout << appName << std::endl;
return true;
}
bool CSeqCtrlService::start(int argc, char *argv[], int &/*nStatus*/)
{
//< 进行相关的资源初始化,业务逻辑需要开一个线程进行处理,不能在本函数中一直循环处理
//< 本函数返回true主线程就会进入阻塞状态等待退出指令
//< 本函数返回false就代表启动失败
std::string appName;
bool isMaster = false;
if (!parseCommandLine(argc, argv, appName, isMaster))
{
std::cerr << "参数解析失败" << std::endl;
return false;
}
iot_public::StartLogSystem(appName.c_str(), SEQUENCE_PROCESSNAME.c_str());
iot_public::initI18N("sequence_server/translate","sequence_server");
if (!getAppInfo(appName, m_stRunAppInfo))
{
return false;
}
if (CAppService::isAlreadyRunning(m_stRunAppInfo.strAppName))
{
return false;
}
if (!initMsgBus())
{
return false;
}
if (!CAppService::initService(m_stRunAppInfo, m_strStartArgs))
{
return false;
}
if (!CDbSaveCtrl::initDbSave(m_stRunAppInfo.nDomainId,m_stRunAppInfo.nAppId))
{
LOGERROR("历史服务初始化失败!");
return false;
}
if (isMaster)
{
redundantSwitch(true, false);
}
return true;
}
bool CSeqCtrlService::stop()
{
deleteThread();
CDbSaveCtrl::releaseDbSave();
CAppService::quitService();
iot_net::releaseMsgBus();
iot_public::StopLogSystem();
return true;
}
bool CSeqCtrlService::getAppInfo(
const std::string &strAppName,
iot_public::SRunAppInfo & info)
{
iot_public::CSysInfoInterfacePtr sysInfoPtr;
if (iot_public::createSysInfoInstance(sysInfoPtr) == false)
{
return false;
}
int nRet = sysInfoPtr->getLocalRunAppInfoByName(strAppName, info);
if (0 != nRet) {
LOGERROR("获取app运行信息失败!(return 0)");
return false;
}
return true;
}
bool CSeqCtrlService::initMsgBus()
{
if (!iot_net::initMsgBus(SEQUENCE_PROCESSNAME.c_str(),
getInstanceName(m_stRunAppInfo.strAppName).c_str()))
{
LOGERROR("初始化消息总线失败");
return false;
}
return true;
}
bool CSeqCtrlService::creatThread()
{
if (NULL == m_ptrSeqCtrlServiceThread)
{
m_ptrSeqCtrlServiceThread =
boost::make_shared<CSeqServiceThread>(m_stRunAppInfo);
if (m_ptrSeqCtrlServiceThread == NULL)
{
LOGERROR("创建顺控服务主线程失败!");
return false;
}
m_ptrSeqCtrlServiceThread->resume();
}
return true;
}
bool CSeqCtrlService::deleteThread()
{
if (NULL != m_ptrSeqCtrlServiceThread)
{
m_ptrSeqCtrlServiceThread->quit();
m_ptrSeqCtrlServiceThread.reset();
}
return true;
}
bool CSeqCtrlService::testThead()
{
m_ptrTestThread = boost::make_shared<boost::thread>(
boost::bind(&CSeqCtrlService::testTheadPro,
this));
return true;
}
void CSeqCtrlService::testTheadPro()
{
int i = 0;
while (i < 100)
{
creatThread();
using namespace boost::posix_time;
using namespace boost::this_thread;
sleep(seconds(3));
deleteThread();
i++;
}
}
int CSeqCtrlService::redundantSwitch(bool bMaster, bool bSlave)
{
LOGINFO("接收到主备服务切换,主[%d],备[%d]!",
bMaster,
bSlave
);
if (bMaster)
{
creatThread();
}
else
{
deleteThread();
}
CAppService::redundantSwitch(bMaster, bSlave);
return 0;
}