#include #include #include "maintenance.h" #include #include "bindTimerTask.h" #include #include #include namespace po = boost::program_options; namespace P2PVR { MaintenanceI::Options::Options() : IceTray::Options("P2PVR Maintenance options") { } ICETRAY_OPTIONS(MaintenanceI::Options, ("p2pvr.maintenance.periodUpdateNetwork", po::value(&periodUpdateNetwork)->default_value(86400 * 7), "Period between automated updates of DVB network (1 week)") ("p2pvr.maintenance.periodUpdateServices", po::value(&periodUpdateServices)->default_value(86400 * 7), "Period between automated updates of DVB services (1 week)") ("p2pvr.maintenance.periodUpdateEvents", po::value(&periodUpdateEvents)->default_value(3600 * 12), "Period between automated updates of DVB events (12 hours)") ("p2pvr.maintenance.scanOnStart", po::value(&scanOnStart)->default_value(false), "Perform the maintenance circle on start-up (false)") ); IceTray::Logging::LoggerPtr MaintenanceI::logger(LOGMANAGER()->getLogger()); MaintenanceI::MaintenanceI(IceTray::DatabasePoolPtr db, Ice::ObjectAdapterPtr a, IceUtil::TimerPtr t) : IceTray::AbstractDatabaseClient(db), adapter(a), timer(t), clientCheck(new BindTimerTask(boost::bind(&MaintenanceI::ScheduledUpdate, this))), lastUpdateNetwork(0), lastUpdateServices(0), lastUpdateEvents(0), updateRunning(false) { if (timer) { timer->scheduleRepeated(clientCheck, IceUtil::Time::seconds(5 * 60)); } if (options->scanOnStart) { ScheduledUpdate(); } } void MaintenanceI::UpdateAll(const Ice::Current & ice) { UpdateAll(FE_OFDM, ice); UpdateAll(FE_QPSK, ice); UpdateAll(FE_ATSC, ice); UpdateAll(FE_QAM, ice); } void MaintenanceI::UpdateAll(short type, const Ice::Current & ice) { UpdateNetwork(type, ice); UpdateServices(ice); UpdateEvents(ice); } void MaintenanceI::ScheduledUpdate() { logger->messagebf(LOG::DEBUG, "%s: triggered", __PRETTY_FUNCTION__); if (!updateRunning) { std::thread update([this] { try { AdHoc::ScopeExit notRunning([this]{ updateRunning = false; }); updateRunning = true; time_t now = time(NULL); if (lastUpdateNetwork < now - options->periodUpdateNetwork) { logger->messagebf(LOG::INFO, "%s: updating network", __PRETTY_FUNCTION__); this->UpdateNetwork(FE_OFDM, Ice::Current()); time(&lastUpdateNetwork); } if (lastUpdateServices < now - options->periodUpdateServices) { logger->messagebf(LOG::INFO, "%s: updating services", __PRETTY_FUNCTION__); this->UpdateServices(Ice::Current()); time(&lastUpdateServices); } if (lastUpdateEvents < now - options->periodUpdateEvents) { logger->messagebf(LOG::INFO, "%s: updating events", __PRETTY_FUNCTION__); this->UpdateEvents(Ice::Current()); time(&lastUpdateEvents); } logger->messagebf(LOG::DEBUG, "%s: completed", __PRETTY_FUNCTION__); } catch (const std::exception & ex) { char * buf = __cxxabiv1::__cxa_demangle(typeid(ex).name(), NULL, NULL, NULL); logger->messagebf(LOG::ERR, "%s: failed %s: %s", __PRETTY_FUNCTION__, buf, ex.what()); free(buf); } catch (...) { logger->messagebf(LOG::ERR, "%s: failed (unknown exception)", __PRETTY_FUNCTION__); } }); update.detach(); } } }