WIP. Reorganizing things to get settings work. First attempt on Database settings

This commit is contained in:
emeric
2014-07-22 12:57:29 +02:00
parent f1cea2404e
commit 938e96cc40
32 changed files with 752 additions and 96 deletions
+44
View File
@@ -0,0 +1,44 @@
#include <boost/thread.hpp>
#include "DatabaseUpdateService.hpp"
DatabaseUpdateService::DatabaseUpdateService(boost::asio::io_service& ioService, const boost::filesystem::path& p)
: _metadataParser(),
_databaseUpdater( p, _metadataParser)
{
}
void
DatabaseUpdateService::start(void)
{
// TODO
// Read database parameters and program a timer for the next scan
// _thread = boost::thread(boost::bind(&DatabaseUpdater::Updater::process, &_databaseUpdater));
}
void
DatabaseUpdateService::stop(void)
{
std::cout << "DatabaseUpdateService::stop, processing..." << std::endl;
// no effect if thread does not exist
_thread.interrupt();
_thread.join();
std::cout << "DatabaseUpdateService::stop, process done" << std::endl;
}
void
DatabaseUpdateService::restart(void)
{
std::cout << "DatabaseUpdateService::restart" << std::endl;
stop();
start();
}
bool
DatabaseUpdateService::isScanning(void) const
{
// scanning is active only if a thread is running the updater
return _thread.get_id() != boost::thread::id();
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef DB_UPDATE_SERVICE_HPP
#define DB_UPDATE_SERVICE_HPP
#include <boost/thread.hpp>
#include <boost/asio/io_service.hpp>
#include "metadata/AvFormat.hpp"
#include "database-updater/DatabaseUpdater.hpp"
#include "Service.hpp"
class DatabaseUpdateService : public Service
{
public:
typedef std::shared_ptr<DatabaseUpdateService> pointer;
DatabaseUpdateService(boost::asio::io_service& ioService, const boost::filesystem::path& p);
// Service interface
void start(void);
void stop(void);
void restart(void);
// Specific interface
bool isScanning(void) const; //return if the service is currently scanning the db
private:
boost::thread _thread;
MetaData::AvFormat _metadataParser;
DatabaseUpdater::Updater _databaseUpdater; // Todo use handler
};
#endif
+28
View File
@@ -0,0 +1,28 @@
#include "RemoteServerService.hpp"
RemoteServerService::RemoteServerService(boost::asio::io_service& ioService, const Remote::Server::Server::endpoint_type& endpoint, boost::filesystem::path dbPath)
: _server(ioService, endpoint, dbPath)
{
}
void
RemoteServerService::start(void)
{
std::cout << "RemoteServerService::start, starting..." << std::endl;
_server.run();
}
void
RemoteServerService::stop(void)
{
std::cout << "RemoteServerService::stop, stopping..." << std::endl;
_server.stop();
}
void
RemoteServerService::restart(void)
{
std::cout << "RemoteServerService::restart, not implemented!" << std::endl;
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef REMOTE_SERVER_SERVICE_HPP
#define REMOTE_SERVER_SERVICE_HPP
#include <boost/filesystem.hpp>
#include "Service.hpp"
#include "remote/server/Server.hpp"
class RemoteServerService : public Service
{
public:
RemoteServerService(boost::asio::io_service& ioService, const Remote::Server::Server::endpoint_type& endpoint, boost::filesystem::path dbPath);
void start(void);
void stop(void);
void restart(void);
private:
Remote::Server::Server _server;
};
#endif
+28
View File
@@ -0,0 +1,28 @@
#ifndef SERVICE_HPP
#define SERVICE_HPP
#include <boost/thread.hpp>
#include <memory>
#include <set>
// Interface class wrapper for running services
class Service
{
public:
typedef std::shared_ptr<Service> pointer;
Service(const Service&) = delete;
Service& operator=(const Service&) = delete;
Service() {}
virtual ~Service() {}
virtual void start(void) = 0;
virtual void stop(void) = 0;
virtual void restart(void) = 0;
};
#endif
+118
View File
@@ -0,0 +1,118 @@
//#include <csignal>
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include "ServiceManager.hpp"
ServiceManager&
ServiceManager::instance()
{
static ServiceManager instance;
return instance;
}
ServiceManager::ServiceManager()
: _signalSet(_ioService)
{
_signalSet.add(SIGINT);
_signalSet.add(SIGTERM);
#if defined(SIGQUIT)
_signalSet.add(SIGQUIT);
#endif // defined(SIGQUIT)
_signalSet.add(SIGHUP);
}
ServiceManager::~ServiceManager()
{
stopServices();
}
void
ServiceManager::run()
{
asyncWaitSignals();
std::cout << "ServiceManager::run Waiting for events..." << std::endl;
try {
// Wait for events
_ioService.run();
}
catch( std::exception& e )
{
std::cerr << "Caugh exception in service : " << e.what() << std::endl;
stopServices();
}
std::cout << "ServiceManager::run complete!" << std::endl;
}
void
ServiceManager::asyncWaitSignals(void)
{
_signalSet.async_wait(boost::bind(&ServiceManager::handleSignal,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::signal_number));
}
void
ServiceManager::startService(Service::pointer service)
{
std::cout << "ServiceManager::startService" << std::endl;
_services.insert(service);
service->start();
std::cout << "ServiceManager::startService done" << std::endl;
}
void
ServiceManager::stopService(Service::pointer service)
{
_services.erase(service);
service->stop();
}
void
ServiceManager::stopServices(void)
{
BOOST_FOREACH(Service::pointer service, _services)
service->stop();
}
void
ServiceManager::restartServices(void)
{
BOOST_FOREACH(Service::pointer service, _services)
service->restart();
}
void
ServiceManager::handleSignal(boost::system::error_code /*ec*/, int signo)
{
std::cout << "Received signal " << signo << std::endl;
switch (signo)
{
case SIGINT:
case SIGTERM:
case SIGQUIT:
std::cout << "Stopping services..." << std::endl;
stopServices();
// Do not listen for signals, this will make the ioservice.run return
break;
case SIGHUP:
std::cout << "Restarting services..." << std::endl;
restartServices();
asyncWaitSignals();
break;
default:
assert(0);
}
}
+70
View File
@@ -0,0 +1,70 @@
#ifndef SERVICE_CONTROLER_HPP
#define SERVICE_CONTROLER_HPP
#include <boost/asio.hpp>
#include <set>
#include "Service.hpp"
// Start/Stop/Reload Services
class ServiceManager
{
public:
static ServiceManager& instance();
~ServiceManager();
void stopService(Service::pointer service);
void startService(Service::pointer service);
void stopAllServices();
// Return in case of failure/stop by user
void run();
boost::asio::io_service& getIoService() {return _ioService;}
const boost::asio::io_service& getIoService() const {return _ioService;}
template <class T> typename T::pointer getService();
boost::mutex& mutex() { return _mutex;}
private:
ServiceManager();
ServiceManager(ServiceManager const&); // Don't Implement
void operator=(ServiceManager const&); // Don't implement
void restartServices(void);
void stopServices(void);
void asyncWaitSignals(void);
void handleSignal(boost::system::error_code error, int signo);
boost::mutex _mutex;
boost::asio::io_service _ioService;
// Listen for interesting signals
boost::asio::signal_set _signalSet;
std::set<Service::pointer> _services;
};
template <class T> typename T::pointer
ServiceManager::getService()
{
std::set<Service::pointer>::iterator it;
for (std::set<Service::pointer>::iterator it = _services.begin(); it != _services.end(); ++it)
{
if (typeid(*(*it)) == typeid(T)) {
return std::dynamic_pointer_cast<T>(*it);
}
}
return std::shared_ptr<T>();
}
#endif
+38
View File
@@ -0,0 +1,38 @@
#include <iostream>
#include <iomanip>
#include "UserInterfaceService.hpp"
#include "ui/LmsApplication.hpp"
UserInterfaceService::UserInterfaceService( int argc, char* argv[], boost::filesystem::path dbPath)
: _server(argv[0], "")
{
// TODO configure server using another way (config file?)
_server.setServerConfiguration (argc, argv, WTHTTP_CONFIGURATION);
// bind entry point
_server.addEntryPoint(Wt::Application, boost::bind(UserInterface::LmsApplication::create, _1, dbPath));
}
void
UserInterfaceService::start(void)
{
_server.start();
std::cout << "UserInterfaceService::start -> Service started..." << std::endl;
}
void
UserInterfaceService::stop(void)
{
std::cout << "UserInterfaceService::stop -> stopping..." << std::endl;
_server.stop();
std::cout << "UserInterfaceService::stop -> stopped!" << std::endl;
}
void
UserInterfaceService::restart(void)
{
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef WEB_SERVER_SERVICE_HPP
#define WEB_SERVER_SERVICE_HPP
#include <boost/filesystem.hpp>
#include <Wt/WServer>
#include "Service.hpp"
class UserInterfaceService : public Service
{
public:
UserInterfaceService( int argc, char* argv[], boost::filesystem::path dbPath);
void start(void);
void stop(void);
void restart(void);
private:
Wt::WServer _server;
};
#endif