268 lines
5.9 KiB
C++
268 lines
5.9 KiB
C++
#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;
|
||
}
|