1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#include <logger.h>
#include <thread>
#include "maintenance.h"
#include <Ice/Ice.h>
#include "bindTimerTask.h"
#include <linux/dvb/frontend.h>
#include <cxxabi.h>
#include <scopeExit.h>
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::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();
}
}
}
|