#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(), "app name") (OPT_DESC_AUTO_MASTER",m", po::value(), "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(); } else { isMaster = false; } if (vm.count(OPT_DESC_APP) == 0) { appName = "base"; LOGWARN("没有输入启动参数,使用默认参数base!"); } else { appName = vm[OPT_DESC_APP].as(); } } 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; } kbd_public::StartLogSystem(appName.c_str(), SEQUENCE_PROCESSNAME.c_str()); kbd_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(); kbd_net::releaseMsgBus(); kbd_public::StopLogSystem(); return true; } bool CSeqCtrlService::getAppInfo( const std::string &strAppName, kbd_public::SRunAppInfo & info) { kbd_public::CSysInfoInterfacePtr sysInfoPtr; if (kbd_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 (!kbd_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(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::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; }