268 lines
5.9 KiB
C++
Raw Normal View History

#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;
}
2025-03-12 14:17:53 +08:00
iot_public::StartLogSystem(appName.c_str(), SEQUENCE_PROCESSNAME.c_str());
2025-03-12 14:17:53 +08:00
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();
2025-03-12 14:17:53 +08:00
iot_net::releaseMsgBus();
iot_public::StopLogSystem();
return true;
}
bool CSeqCtrlService::getAppInfo(
const std::string &strAppName,
2025-03-12 14:17:53 +08:00
iot_public::SRunAppInfo & info)
{
2025-03-12 14:17:53 +08:00
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()
{
2025-03-12 14:17:53 +08:00
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;
}