summaryrefslogtreecommitdiff
path: root/p2pvr/daemon/maintenance.cpp
blob: 928e8d98653446a3b45725b2962865d255d40005 (plain)
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
#include <pch.hpp>
#include <logger.h>
#include <thread>
#include "maintenance.h"
#include <Ice/Ice.h>
#include "bindTimerTask.h"
#include <linux/dvb/frontend.h>
#include <cxxabi.h>

time_t Maintenance::periodUpdateNetwork;
time_t Maintenance::periodUpdateServices;
time_t Maintenance::periodUpdateEvents;

DECLARE_OPTIONS(Maintenance, "P2PVR Maintenance options")
("p2pvr.maintenance.periodUpdateNetwork", Options::value(&periodUpdateNetwork, 86400 * 7),
 "Period between automated updates of DVB network (1 week)")
("p2pvr.maintenance.periodUpdateServices", Options::value(&periodUpdateServices, 86400 * 7),
 "Period between automated updates of DVB services (1 week)")
("p2pvr.maintenance.periodUpdateEvents", Options::value(&periodUpdateEvents, 3600 * 12),
 "Period between automated updates of DVB events (12 hours)")
END_OPTIONS(Maintenance);

Maintenance::Maintenance(Ice::ObjectAdapterPtr a, IceUtil::TimerPtr t) :
	adapter(a),
	timer(t),
	clientCheck(new BindTimerTask(boost::bind(&Maintenance::ScheduledUpdate, this))), 
	lastUpdateNetwork(0),
	lastUpdateServices(0),
	lastUpdateEvents(0),
	updateRunning(false)
{
	if (timer) {
		timer->scheduleRepeated(clientCheck, IceUtil::Time::seconds(5 * 60));
	}
#ifdef NDEBUG
	ScheduledUpdate();
#endif
}

void
Maintenance::UpdateAll(const Ice::Current & ice)
{
	UpdateAll(FE_OFDM, ice);
	UpdateAll(FE_QPSK, ice);
	UpdateAll(FE_ATSC, ice);
	UpdateAll(FE_QAM, ice);
}

void
Maintenance::UpdateAll(short type, const Ice::Current & ice)
{
	UpdateNetwork(type, ice);
	UpdateServices(ice);
	UpdateEvents(ice);
}

void
Maintenance::ScheduledUpdate()
{
	Logger()->messagebf(LOG_DEBUG, "%s: triggered", __PRETTY_FUNCTION__);
	if (!updateRunning) {
		std::thread update([this] {
				try {
					ScopeObject notRunning([this]{ updateRunning = false; });
					updateRunning = true;
					auto si = P2PVR::MaintenancePrx::checkedCast(adapter->createProxy(adapter->getCommunicator()->stringToIdentity("Maintenance")));
					time_t now = time(NULL);
					if (lastUpdateNetwork < now - periodUpdateNetwork) {
						Logger()->messagebf(LOG_INFO, "%s: updating network", __PRETTY_FUNCTION__);
						si->UpdateNetwork(FE_OFDM);
						time(&lastUpdateNetwork);
					}
					if (lastUpdateServices < now - periodUpdateServices) {
						Logger()->messagebf(LOG_INFO, "%s: updating services", __PRETTY_FUNCTION__);
						si->UpdateServices();
						time(&lastUpdateServices);
					}
					if (lastUpdateEvents < now - periodUpdateEvents) {
						Logger()->messagebf(LOG_INFO, "%s: updating events", __PRETTY_FUNCTION__);
						si->UpdateEvents();
						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();
	}
}