WIP: writing daemon + reloadable

This commit is contained in:
Naim A 2016-01-23 18:31:43 -08:00
parent 9d319aa946
commit 2b594fd418
4 changed files with 141 additions and 48 deletions

View file

@ -30,20 +30,50 @@
#include "udpTracker.hpp" #include "udpTracker.hpp"
#include "http/httpserver.hpp" #include "http/httpserver.hpp"
#include "http/webapp.hpp" #include "http/webapp.hpp"
#include "tracker.hpp"
UDPT::Logger *logger; UDPT::Logger *logger = NULL;
UDPT::Tracker *instance = NULL;
static void _signal_handler (int sig) static void _signal_handler (int sig)
{ {
std::stringstream ss; switch (sig)
ss << "Signal " << sig << " raised. "; {
logger->log(Logger::LL_INFO, ss.str()); case SIGTERM:
instance->stop();
break;
case SIGHUP:
break;
}
} }
#ifdef linux
static void daemonize(const boost::program_options::variables_map& conf)
{
if (1 == ::getppid()) return; // already a daemon
int r = ::fork();
if (0 > r) ::exit(-1); // failed to daemonize.
if (0 < r) ::exit(0); // parent exists.
::umask(0);
::setsid();
// close all fds.
for (int i = ::getdtablesize(); i >=0; --i)
{
::close(i);
}
::chdir(conf["daemon.chdir"].as<std::string>().c_str());
}
#endif
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int r; Tracker& tracker = UDPT::Tracker::getInstance();
instance = &tracker;
#ifdef WIN32 #ifdef WIN32
WSADATA wsadata; WSADATA wsadata;
@ -56,6 +86,9 @@ int main(int argc, char *argv[])
("all-help", "displays all help") ("all-help", "displays all help")
("test,t", "test configuration file") ("test,t", "test configuration file")
("config,c", boost::program_options::value<std::string>()->default_value("/etc/udpt.conf"), "configuration file to use") ("config,c", boost::program_options::value<std::string>()->default_value("/etc/udpt.conf"), "configuration file to use")
#ifdef linux
("interactive,i", "doesn't start as daemon")
#endif
; ;
boost::program_options::options_description configOptions("Configuration options"); boost::program_options::options_description configOptions("Configuration options");
@ -77,6 +110,10 @@ int main(int argc, char *argv[])
("logging.filename", boost::program_options::value<std::string>()->default_value("stdout"), "file to write logs to") ("logging.filename", boost::program_options::value<std::string>()->default_value("stdout"), "file to write logs to")
("logging.level", boost::program_options::value<std::string>()->default_value("warning"), "log level (error/warning/info/debug)") ("logging.level", boost::program_options::value<std::string>()->default_value("warning"), "log level (error/warning/info/debug)")
#ifdef linux
("daemon.chdir", boost::program_options::value<std::string>()->default_value("/"), "home directory for daemon")
#endif
; ;
boost::program_options::variables_map var_map; boost::program_options::variables_map var_map;
@ -125,22 +162,11 @@ int main(int argc, char *argv[])
} }
} }
#ifdef SIGBREAK std::shared_ptr<UDPT::Logger> spLogger;
signal(SIGBREAK, &_signal_handler);
#endif
#ifdef SIGTERM
signal(SIGTERM, &_signal_handler);
#endif
#ifdef SIGABRT
signal(SIGABRT, &_signal_handler);
#endif
#ifdef SIGINT
signal(SIGINT, &_signal_handler);
#endif
try try
{ {
logger = new UDPT::Logger(var_map); spLogger = std::shared_ptr<UDPT::Logger>(new UDPT::Logger(var_map));
logger = spLogger.get();
} }
catch (const std::exception& ex) catch (const std::exception& ex)
{ {
@ -148,39 +174,19 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
std::shared_ptr<UDPTracker> tracker; #ifdef linux
std::shared_ptr<UDPT::Server::HTTPServer> apiSrv; if (!var_map.count("interactive"))
std::shared_ptr<UDPT::Server::WebApp> webApp;
try
{ {
tracker = std::shared_ptr<UDPTracker>(new UDPTracker(var_map)); daemonize(var_map);
tracker->start();
if (var_map["apiserver.enable"].as<bool>())
{
try
{
apiSrv = std::shared_ptr<UDPT::Server::HTTPServer>(new UDPT::Server::HTTPServer(var_map));
webApp = std::shared_ptr<UDPT::Server::WebApp>(new UDPT::Server::WebApp(apiSrv, tracker->conn, var_map));
webApp->deploy();
}
catch (const UDPT::Server::ServerException &e)
{
std::cerr << "ServerException #" << e.getErrorCode() << ": " << e.getErrorMsg() << endl;
}
}
}
catch (const UDPT::UDPTException& ex)
{
std::cerr << "UDPTException: " << ex.what() << std::endl;
} }
::signal(SIGHUP, _signal_handler);
::signal(SIGTERM, _signal_handler);
#endif
std::cout << "Hit Control-C to exit." << endl; tracker.start(var_map);
tracker.wait();
tracker->wait(); std::cerr << "Bye." << std::endl;
std::cout << endl << "Goodbye." << endl;
#ifdef WIN32 #ifdef WIN32
::WSACleanup(); ::WSACleanup();

View file

@ -36,11 +36,13 @@
#elif defined (linux) #elif defined (linux)
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <unistd.h> #include <unistd.h>
#include <netdb.h> #include <netdb.h>
#include <pthread.h> #include <pthread.h>
#include <fcntl.h>
#define SOCKET int #define SOCKET int
#define INVALID_SOCKET 0 #define INVALID_SOCKET 0

50
src/tracker.cpp Normal file
View file

@ -0,0 +1,50 @@
#include "tracker.hpp"
namespace UDPT
{
Tracker::Tracker()
{
}
Tracker::~Tracker()
{
}
void Tracker::stop()
{
m_udpTracker->stop();
wait();
m_apiSrv = nullptr;
m_webApp = nullptr;
m_udpTracker = nullptr;
}
void Tracker::wait()
{
m_udpTracker->wait();
}
void Tracker::start(const boost::program_options::variables_map& conf)
{
m_udpTracker = std::shared_ptr<UDPTracker>(new UDPTracker(conf));
if (conf["apiserver.enable"].as<bool>())
{
m_apiSrv = std::shared_ptr<UDPT::Server::HTTPServer>(new UDPT::Server::HTTPServer(conf));
m_webApp = std::shared_ptr<UDPT::Server::WebApp>(new UDPT::Server::WebApp(m_apiSrv, m_udpTracker->conn, conf));
m_webApp->deploy();
}
m_udpTracker->start();
}
Tracker& Tracker::getInstance()
{
static Tracker s_tracker;
return s_tracker;
}
}

35
src/tracker.hpp Normal file
View file

@ -0,0 +1,35 @@
#pragma once
#include <memory>
#include <boost/program_options.hpp>
#include "logging.h"
#include "multiplatform.h"
#include "udpTracker.hpp"
#include "http/httpserver.hpp"
#include "http/webapp.hpp"
namespace UDPT
{
class Tracker
{
public:
virtual ~Tracker();
void stop();
void start(const boost::program_options::variables_map& conf);
void wait();
static Tracker& getInstance();
private:
std::shared_ptr<UDPT::UDPTracker> m_udpTracker;
std::shared_ptr<UDPT::Server::HTTPServer> m_apiSrv;
std::shared_ptr<UDPT::Server::WebApp> m_webApp;
Tracker();
};
}