2025-03-12 10:03:16 +08:00
|
|
|
|
#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 10:03:16 +08:00
|
|
|
|
|
2025-03-12 14:17:53 +08:00
|
|
|
|
iot_public::initI18N("sequence_server/translate","sequence_server");
|
2025-03-12 10:03:16 +08:00
|
|
|
|
|
|
|
|
|
|
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();
|
2025-03-12 10:03:16 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CSeqCtrlService::getAppInfo(
|
|
|
|
|
|
const std::string &strAppName,
|
2025-03-12 14:17:53 +08:00
|
|
|
|
iot_public::SRunAppInfo & info)
|
2025-03-12 10:03:16 +08:00
|
|
|
|
{
|
2025-03-12 14:17:53 +08:00
|
|
|
|
iot_public::CSysInfoInterfacePtr sysInfoPtr;
|
|
|
|
|
|
if (iot_public::createSysInfoInstance(sysInfoPtr) == false)
|
2025-03-12 10:03:16 +08:00
|
|
|
|
{
|
|
|
|
|
|
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(),
|
2025-03-12 10:03:16 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|