MythTV  master
housekeeper.cpp
Go to the documentation of this file.
1 /* -*- Mode: c++ -*-
2 *
3 * Class HouseKeeperTask
4 * Class HouseKeeperThread
5 * Class HouseKeeper
6 *
7 * Copyright (C) Raymond Wagner 2013
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23 
24 
25 
52 #include <chrono>
53 #include <utility>
54 
55 #include <QMutexLocker>
56 
57 #include "mythevent.h"
58 #include "mythdbcon.h"
59 #include "housekeeper.h"
60 #include "mythcorecontext.h"
61 
62 using namespace std::chrono_literals;
63 
102  ReferenceCounter(dbTag), m_dbTag(dbTag), m_scope(scope),
103  m_startup(startup),
104  m_lastRun(MythDate::fromSecsSinceEpoch(0)),
105  m_lastSuccess(MythDate::fromSecsSinceEpoch(0)),
106  m_lastUpdate(MythDate::fromSecsSinceEpoch(0))
107 {
108 }
109 
110 bool HouseKeeperTask::CheckRun(const QDateTime& now)
111 {
112  LOG(VB_GENERAL, LOG_DEBUG, QString("Checking to run %1").arg(GetTag()));
113  bool check = false;
114  if (!m_confirm && !m_running && (check = DoCheckRun(now)))
115  {
116  // if m_confirm is already set, the task is already in the queue
117  // and should not be queued a second time
118  m_confirm = true;
119  }
120  return check;
121 }
122 
124 {
125  return ((m_startup == kHKRunImmediateOnStartup) &&
127 }
128 
130 {
132  {
133  m_confirm = true;
134  return true;
135  }
136  return false;
137 }
138 
140 {
141  LOG(VB_GENERAL, LOG_INFO, QString("Running HouseKeeperTask '%1'.")
142  .arg(m_dbTag));
143  if (m_running)
144  {
145  // something else is already running me, bail out
146  LOG(VB_GENERAL, LOG_WARNING, QString("HouseKeeperTask '%1' already "
147  "running. Refusing to run concurrently").arg(m_dbTag));
148  return false;
149  }
150 
151  m_running = true;
152  bool res = DoRun();
153  m_running = false;
154  if (!res)
155  {
156  LOG(VB_GENERAL, LOG_INFO, QString("HouseKeeperTask '%1' Failed.")
157  .arg(m_dbTag));
158  }
159  else
160  {
161  LOG(VB_GENERAL, LOG_INFO,
162  QString("HouseKeeperTask '%1' Finished Successfully.")
163  .arg(m_dbTag));
164  }
165  return res;
166 }
167 
169 {
170  QueryLast();
171  return m_lastRun;
172 }
173 
175 {
176  QueryLast();
177  return m_lastRun;
178 }
179 
181 {
182  if (m_scope != kHKInst)
183  {
184  if (m_lastUpdate.addSecs(30) > MythDate::current())
185  // just to cut down on unnecessary queries
186  return;
187 
189 
192 
193  if (m_scope == kHKGlobal)
194  {
195  query.prepare("SELECT lastrun,lastsuccess FROM housekeeping"
196  " WHERE tag = :TAG"
197  " AND hostname IS NULL");
198  }
199  else
200  {
201  query.prepare("SELECT lastrun,lastsuccess FROM housekeeping"
202  " WHERE tag = :TAG"
203  " AND hostname = :HOST");
205  }
206 
207  query.bindValue(":TAG", m_dbTag);
208 
209  if (query.exec() && query.next())
210  {
211  m_lastRun = MythDate::as_utc(query.value(0).toDateTime());
212  m_lastSuccess = MythDate::as_utc(query.value(1).toDateTime());
213  }
214  }
215 
217 }
218 
219 QDateTime HouseKeeperTask::UpdateLastRun(const QDateTime& last, bool successful)
220 {
221  m_lastRun = last;
222  if (successful)
223  m_lastSuccess = last;
224  m_confirm = false;
225 
226  if (m_scope != kHKInst)
227  {
229  if (!query.isConnected())
230  return last;
231 
233  {
234  // not previously set, perform insert
235 
236  if (m_scope == kHKGlobal)
237  {
238  query.prepare("INSERT INTO housekeeping"
239  " (tag, lastrun, lastsuccess)"
240  " VALUES (:TAG, :TIME, :STIME)");
241  }
242  else
243  {
244  query.prepare("INSERT INTO housekeeping"
245  " (tag, hostname, lastrun, lastsuccess)"
246  " VALUES (:TAG, :HOST, :TIME, :STIME)");
247  }
248  }
249  else
250  {
251  // previously set, perform update
252 
253  if (m_scope == kHKGlobal)
254  {
255  query.prepare("UPDATE housekeeping SET lastrun=:TIME,"
256  " lastsuccess=:STIME"
257  " WHERE tag = :TAG"
258  " AND hostname IS NULL");
259  }
260  else
261  {
262  query.prepare("UPDATE housekeeping SET lastrun=:TIME,"
263  " lastsuccess=:STIME"
264  " WHERE tag = :TAG"
265  " AND hostname = :HOST");
266  }
267  }
268 
269  if (m_scope == kHKGlobal)
270  {
271  LOG(VB_GENERAL, LOG_DEBUG,
272  QString("Updating global run time for %1").arg(m_dbTag));
273  }
274  else
275  {
276  LOG(VB_GENERAL, LOG_DEBUG,
277  QString("Updating local run time for %1").arg(m_dbTag));
278  }
279 
280  if (m_scope == kHKLocal)
282  query.bindValue(":TAG", m_dbTag);
285 
286  if (!query.exec())
287  MythDB::DBError("HouseKeeperTask::updateLastRun", query);
288  }
289 
290  QString msg;
291  if (successful)
292  msg = QString("HOUSE_KEEPER_SUCCESSFUL %1 %2 %3");
293  else
294  msg = QString("HOUSE_KEEPER_RUNNING %1 %2 %3");
295  msg = msg.arg(gCoreContext->GetHostName())
296  .arg(m_dbTag)
300 
301  return last;
302 }
303 
304 void HouseKeeperTask::SetLastRun(const QDateTime &last, bool successful)
305 {
306  m_lastRun = last;
307  if (successful)
308  m_lastSuccess = last;
309 
311 }
312 
327  int period, float min, float max, int retry,
329  HouseKeeperTask(dbTag, scope, startup), m_period(period), m_retry(retry),
330  m_windowPercent(min, max), m_currentProb(1.0)
331 {
333  if (m_retry == 0)
334  m_retry = m_period;
335 }
336 
338 {
339  int period = m_period;
340  if (GetLastRun() > GetLastSuccess())
341  {
342  // last attempt was not successful
343  // try shortened period
344  period = m_retry;
345  }
346 
347  m_windowElapsed.first =
348  (uint32_t)((float)period * m_windowPercent.first);
349  m_windowElapsed.second =
350  (uint32_t)((float)period * m_windowPercent.second);
351 }
352 
353 void PeriodicHouseKeeperTask::SetWindow(float min, float max)
354 {
355  m_windowPercent.first = min;
356  m_windowPercent.second = max;
357  CalculateWindow();
358 }
359 
360 QDateTime PeriodicHouseKeeperTask::UpdateLastRun(const QDateTime& last,
361  bool successful)
362 {
363  QDateTime res = HouseKeeperTask::UpdateLastRun(last, successful);
364  CalculateWindow();
365  m_currentProb = 1.0;
366  return res;
367 }
368 
369 void PeriodicHouseKeeperTask::SetLastRun(const QDateTime& last, bool successful)
370 {
371  HouseKeeperTask::SetLastRun(last, successful);
372  CalculateWindow();
373  m_currentProb = 1.0;
374 }
375 
376 bool PeriodicHouseKeeperTask::DoCheckRun(const QDateTime& now)
377 {
378  int elapsed = GetLastRun().secsTo(now);
379 
380  if (elapsed < 0)
381  // something bad has happened. let's just move along
382  return false;
383 
384  if (elapsed < m_windowElapsed.first)
385  // insufficient time elapsed to test
386  return false;
387  if (elapsed > m_windowElapsed.second)
388  // too much time has passed. force run
389  return true;
390 
391  // calculate probability that task should not have yet run
392  // it's backwards, but it makes the math simplier
393  float prob = 1.0F - ((float)(elapsed - m_windowElapsed.first) /
394  (float)(m_windowElapsed.second - m_windowElapsed.first));
395  if (m_currentProb < prob)
396  // more bad stuff
397  return false;
398 
399  // calculate current probability to achieve overall probability
400  // this should be nearly one
401  float prob2 = prob/m_currentProb;
402  // so rand() should have to return nearly RAND_MAX to get a positive
403  // remember, this is computing the probability that up to this point, one
404  // of these tests has returned positive, so each individual test has
405  // a necessarily low probability
406  //
407  // Pseudo-random is good enough. Don't need a true random.
408  // NOLINTNEXTLINE(cert-msc30-c,cert-msc50-cpp)
409  bool res = (rand() > (int)(prob2 * static_cast<float>(RAND_MAX)));
410  m_currentProb = prob;
411 // if (res)
412 // LOG(VB_GENERAL, LOG_DEBUG, QString("%1 will run: this=%2; total=%3")
413 // .arg(GetTag()).arg(1-prob2).arg(1-prob));
414 // else
415 // LOG(VB_GENERAL, LOG_DEBUG, QString("%1 will not run: this=%2; total=%3")
416 // .arg(GetTag()).arg(1-prob2).arg(1-prob));
417  return res;
418 }
419 
420 bool PeriodicHouseKeeperTask::InWindow(const QDateTime& now)
421 {
422  int elapsed = GetLastRun().secsTo(now);
423 
424  if (elapsed < 0)
425  // something bad has happened. let's just move along
426  return false;
427 
428  return (elapsed > m_windowElapsed.first) &&
429  (elapsed < m_windowElapsed.second);
430 }
431 
432 bool PeriodicHouseKeeperTask::PastWindow(const QDateTime &now)
433 {
434  return GetLastRun().secsTo(now) > m_windowElapsed.second;
435 }
436 
452  PeriodicHouseKeeperTask(dbTag, 86400, .5, 1.5, 0, scope, startup),
453  m_windowHour(0, 23)
454 {
456 }
457 
458 DailyHouseKeeperTask::DailyHouseKeeperTask(const QString &dbTag, int minhour,
459  int maxhour, HouseKeeperScope scope, HouseKeeperStartup startup) :
460  PeriodicHouseKeeperTask(dbTag, 86400, .5, 1.5, 0, scope, startup),
461  m_windowHour(minhour, maxhour)
462 {
464 }
465 
467 {
469  QDate date = GetLastRun().addDays(1).date();
470 
471  QDateTime tmp = QDateTime(date, QTime(m_windowHour.first, 0));
472  if (GetLastRun().addSecs(m_windowElapsed.first) < tmp)
473  m_windowElapsed.first = GetLastRun().secsTo(tmp);
474 
475  tmp = QDateTime(date, QTime(m_windowHour.second, 30));
476  // we want to make sure this gets run before the end of the day
477  // so add a 30 minute buffer prior to the end of the window
478  if (GetLastRun().addSecs(m_windowElapsed.second) > tmp)
479  m_windowElapsed.second = GetLastRun().secsTo(tmp);
480 
481  LOG(VB_GENERAL, LOG_DEBUG, QString("%1 Run window between %2 - %3.")
482  .arg(GetTag()).arg(m_windowElapsed.first).arg(m_windowElapsed.second));
483 }
484 
486 {
487  m_windowHour.first = min;
488  m_windowHour.second = max;
489  CalculateWindow();
490 }
491 
492 bool DailyHouseKeeperTask::InWindow(const QDateTime& now)
493 {
495  // parent says we're in the window
496  return true;
497 
498  int hour = now.time().hour();
499  // true if we've missed the window, but we're within our time constraints
500  return PastWindow(now) && (m_windowHour.first <= hour)
501  && (m_windowHour.second > hour);
502 }
503 
515 {
516  RunProlog();
517  m_waitMutex.lock();
518  HouseKeeperTask *task = nullptr;
519 
520  while (m_keepRunning)
521  {
522  m_idle = false;
523 
524  while ((task = m_parent->GetQueuedTask()))
525  {
526  // pull task from housekeeper and process it
527  ReferenceLocker rlock(task);
528 
529  if (!task->ConfirmRun())
530  {
531  // something else has caused the lastrun time to
532  // change since this was requested to run. abort.
533  task = nullptr;
534  continue;
535  }
536 
537  task->UpdateLastRun(false);
538  if (task->Run())
539  task->UpdateLastRun(task->GetLastRun(), true);
540  task = nullptr;
541 
542  if (!m_keepRunning)
543  // thread has been discarded, don't try to start another task
544  break;
545  }
546 
547  m_idle = true;
548 
549  if (!m_keepRunning)
550  // short out rather than potentially hitting another sleep cycle
551  break;
552 
554  }
555 
556  m_waitMutex.unlock();
557  RunEpilog();
558 }
559 
577 {
578  m_timer = new QTimer(this);
579  connect(m_timer, &QTimer::timeout, this, &HouseKeeper::Run);
580  m_timer->setInterval(1min);
581  m_timer->setSingleShot(false);
582 }
583 
585 {
587 
588  if (m_timer)
589  {
590  m_timer->stop();
591  disconnect(m_timer);
592  delete m_timer;
593  m_timer = nullptr;
594  }
595 
596  {
597  // remove anything from the queue first, so it does not start
598  QMutexLocker queueLock(&m_queueLock);
599  while (!m_taskQueue.isEmpty())
600  m_taskQueue.takeFirst()->DecrRef();
601  }
602 
603  {
604  // issue a terminate call to any long-running tasks
605  // this is just a noop unless overwritten by a subclass
606  QMutexLocker mapLock(&m_mapLock);
607  for (auto *it : qAsConst(m_taskMap))
608  it->Terminate();
609  }
610 
611  if (!m_threadList.isEmpty())
612  {
613  QMutexLocker threadLock(&m_threadLock);
614  // tell primary thread to self-terminate and wake it
615  m_threadList.first()->Discard();
616  m_threadList.first()->Wake();
617  // wait for any remaining threads to self-terminate and close
618  while (!m_threadList.isEmpty())
619  {
620  HouseKeepingThread *thread = m_threadList.takeFirst();
621  thread->wait();
622  delete thread;
623  }
624  }
625 
626  {
627  // unload any registered tasks
628  QMutexLocker mapLock(&m_mapLock);
629  QMap<QString,HouseKeeperTask*>::iterator it = m_taskMap.begin();
630  while (it != m_taskMap.end())
631  {
632  (*it)->DecrRef();
633  it = m_taskMap.erase(it);
634  }
635  }
636 }
637 
639 {
640  QMutexLocker mapLock(&m_mapLock);
641  QString tag = task->GetTag();
642  if (m_taskMap.contains(tag))
643  {
644  task->DecrRef();
645  LOG(VB_GENERAL, LOG_ERR,
646  QString("HouseKeeperTask '%1' already registered. "
647  "Rejecting duplicate.").arg(tag));
648  }
649  else
650  {
651  LOG(VB_GENERAL, LOG_INFO,
652  QString("Registering HouseKeeperTask '%1'.").arg(tag));
653  m_taskMap.insert(tag, task);
654  }
655 }
656 
658 {
659  QMutexLocker queueLock(&m_queueLock);
660  HouseKeeperTask *task = nullptr;
661 
662  if (!m_taskQueue.isEmpty())
663  {
664  task = m_taskQueue.dequeue();
665  }
666 
667  // returning nullptr tells the thread that the queue is empty and
668  // to go into standby
669  return task;
670 }
671 
673 {
674  // no need to be fine grained, nothing else should be accessing this map
675  QMutexLocker mapLock(&m_mapLock);
676 
677  if (m_timer->isActive())
678  // Start() should only be called once
679  return;
680 
682  query.prepare("SELECT tag,lastrun"
683  " FROM housekeeping"
684  " WHERE hostname = :HOST"
685  " OR hostname IS NULL");
687 
688  if (!query.exec())
689  MythDB::DBError("HouseKeeper::Run", query);
690  else
691  {
692  while (query.next())
693  {
694  // loop through housekeeping table and load last run timestamps
695  QString tag = query.value(0).toString();
696  QDateTime lastrun = MythDate::as_utc(query.value(1).toDateTime());
697 
698  if (m_taskMap.contains(tag))
699  m_taskMap[tag]->SetLastRun(lastrun);
700  }
701  }
702 
703  gCoreContext->addListener(this);
704 
705  for (auto it = m_taskMap.cbegin(); it != m_taskMap.cend(); ++it)
706  {
707  if ((*it)->CheckImmediate())
708  {
709  // run any tasks marked for immediate operation in-thread
710  (*it)->UpdateLastRun();
711  (*it)->Run();
712  }
713  else if ((*it)->CheckStartup())
714  {
715  // queue any tasks marked for startup
716  LOG(VB_GENERAL, LOG_INFO,
717  QString("Queueing HouseKeeperTask '%1'.").arg(it.key()));
718  QMutexLocker queueLock(&m_queueLock);
719  (*it)->IncrRef();
720  m_taskQueue.enqueue(*it);
721  }
722  }
723 
724  LOG(VB_GENERAL, LOG_INFO, "Starting HouseKeeper.");
725 
726  m_timer->start();
727 }
728 
730 {
731  LOG(VB_GENERAL, LOG_DEBUG, "Running HouseKeeper.");
732 
733  QDateTime now = MythDate::current();
734 
735  QMutexLocker mapLock(&m_mapLock);
736  for (auto it = m_taskMap.begin(); it != m_taskMap.end(); ++it)
737  {
738  if ((*it)->CheckRun(now))
739  {
740  // check if any tasks are ready to run, and add to queue
741  LOG(VB_GENERAL, LOG_INFO,
742  QString("Queueing HouseKeeperTask '%1'.").arg(it.key()));
743  QMutexLocker queueLock(&m_queueLock);
744  (*it)->IncrRef();
745  m_taskQueue.enqueue(*it);
746  }
747  }
748 
749  if (!m_taskQueue.isEmpty())
750  StartThread();
751 
752  if (m_threadList.size() > 1)
753  {
754  // spent threads exist in the thread list
755  // check to see if any have finished up their task and terminated
756  QMutexLocker threadLock(&m_threadLock);
757  int count1 = m_threadList.size();
758 
759  auto it = m_threadList.begin();
760  ++it; // skip the primary thread
761  while (it != m_threadList.end())
762  {
763  if ((*it)->isRunning())
764  ++it;
765  else
766  {
767  delete *it;
768  it = m_threadList.erase(it);
769  }
770  }
771 
772  int count2 = m_threadList.size();
773  if (count1 > count2)
774  {
775  LOG(VB_GENERAL, LOG_DEBUG,
776  QString("Discarded HouseKeepingThreads have completed and "
777  "been deleted. Current count %1 -> %2.")
778  .arg(count1).arg(count2));
779  }
780  }
781 }
782 
797 {
798  QMutexLocker threadLock(&m_threadLock);
799 
800  if (m_threadList.isEmpty())
801  {
802  // we're running for the first time
803  // start up a new thread
804  LOG(VB_GENERAL, LOG_DEBUG, "Running initial HouseKeepingThread.");
805  auto *thread = new HouseKeepingThread(this);
806  m_threadList.append(thread);
807  thread->start();
808  }
809 
810  else if (!m_threadList.first()->isIdle())
811  {
812  // the old thread is still off processing something
813  // discard it and start a new one because we have more stuff
814  // that wants to run
815  LOG(VB_GENERAL, LOG_DEBUG,
816  QString("Current HouseKeepingThread is delayed on task, "
817  "spawning replacement. Current count %1.")
818  .arg(m_threadList.size()));
819  m_threadList.first()->Discard();
820  auto *thread = new HouseKeepingThread(this);
821  m_threadList.prepend(thread);
822  thread->start();
823  }
824 
825  else
826  {
827  // the old thread is idle, so just wake it for processing
828  LOG(VB_GENERAL, LOG_DEBUG, "Waking HouseKeepingThread.");
829  m_threadList.first()->Wake();
830  }
831 }
832 
834 {
835  if (e->type() == MythEvent::MythEventMessage)
836  {
837  auto *me = dynamic_cast<MythEvent*>(e);
838  if (me == nullptr)
839  return;
840  if ((me->Message().left(20) == "HOUSE_KEEPER_RUNNING") ||
841  (me->Message().left(23) == "HOUSE_KEEPER_SUCCESSFUL"))
842  {
843 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
844  QStringList tokens = me->Message()
845  .split(" ", QString::SkipEmptyParts);
846 #else
847  QStringList tokens = me->Message()
848  .split(" ", Qt::SkipEmptyParts);
849 #endif
850  if (tokens.size() != 4)
851  return;
852 
853  QString hostname = tokens[1];
854  QString tag = tokens[2];
855  QDateTime last = MythDate::fromString(tokens[3]);
856  bool successful = me->Message().contains("SUCCESSFUL");
857 
858  QMutexLocker mapLock(&m_mapLock);
859  if (m_taskMap.contains(tag))
860  {
861  if ((m_taskMap[tag]->GetScope() == kHKGlobal) ||
862  ((m_taskMap[tag]->GetScope() == kHKLocal) &&
864  {
865  // task being run in the same scope as us.
866  // update the run time so we don't attempt to run
867  // it ourselves
868  m_taskMap[tag]->SetLastRun(last, successful);
869  }
870  }
871  }
872  }
873 }
ReferenceLocker
This decrements the reference on destruction.
Definition: referencecounter.h:67
HouseKeeperTask::QueryLast
void QueryLast(void)
Definition: housekeeper.cpp:180
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:126
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1420
mythevent.h
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:80
MythEvent::MythEventMessage
static Type MythEventMessage
Definition: mythevent.h:73
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
HouseKeepingThread::m_waitMutex
QMutex m_waitMutex
Definition: housekeeper.h:144
ReferenceCounter::DecrRef
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
Definition: referencecounter.cpp:125
HouseKeeperTask::m_startup
HouseKeeperStartup m_startup
Definition: housekeeper.h:76
HouseKeepingThread::m_keepRunning
bool m_keepRunning
Definition: housekeeper.h:142
DailyHouseKeeperTask::m_windowHour
QPair< int, int > m_windowHour
Definition: housekeeper.h:123
MythDate::as_utc
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
Definition: mythdate.cpp:23
HouseKeeper::m_threadList
QList< HouseKeepingThread * > m_threadList
Definition: housekeeper.h:175
PeriodicHouseKeeperTask::SetLastRun
void SetLastRun(const QDateTime &last, bool successful=true) override
Definition: housekeeper.cpp:369
housekeeper.h
PeriodicHouseKeeperTask::InWindow
virtual bool InWindow(const QDateTime &now)
Definition: housekeeper.cpp:420
HouseKeeperTask::CheckImmediate
bool CheckImmediate(void)
Definition: housekeeper.cpp:123
HouseKeeper::m_threadLock
QMutex m_threadLock
Definition: housekeeper.h:176
HouseKeeperTask::DoCheckRun
virtual bool DoCheckRun(const QDateTime &)
Definition: housekeeper.h:65
HouseKeeperTask::QueryLastRun
QDateTime QueryLastRun(void)
Definition: housekeeper.cpp:168
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:17
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:198
arg
arg(title).arg(filename).arg(doDelete))
mythdbcon.h
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
PeriodicHouseKeeperTask::DoCheckRun
bool DoCheckRun(const QDateTime &now) override
Definition: housekeeper.cpp:376
HouseKeeper::m_taskQueue
QQueue< HouseKeeperTask * > m_taskQueue
Definition: housekeeper.h:169
HouseKeeper::customEvent
void customEvent(QEvent *e) override
Definition: housekeeper.cpp:833
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MThread::RunProlog
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:198
HouseKeeper::RegisterTask
void RegisterTask(HouseKeeperTask *task)
Definition: housekeeper.cpp:638
startup
static int startup()
Definition: mythtv/programs/mythshutdown/main.cpp:771
HouseKeeperTask::m_lastUpdate
QDateTime m_lastUpdate
Definition: housekeeper.h:81
HouseKeeper::Run
void Run(void)
Definition: housekeeper.cpp:729
HouseKeeperTask::UpdateLastRun
QDateTime UpdateLastRun(bool successful=true)
Definition: housekeeper.h:60
PeriodicHouseKeeperTask::PeriodicHouseKeeperTask
PeriodicHouseKeeperTask(const QString &dbTag, int period, float min=0.5, float max=1.1, int retry=0, HouseKeeperScope scope=kHKGlobal, HouseKeeperStartup startup=kHKNormal)
Definition: housekeeper.cpp:326
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
MythEvent::Message
const QString & Message() const
Definition: mythevent.h:65
DailyHouseKeeperTask::InWindow
bool InWindow(const QDateTime &now) override
Definition: housekeeper.cpp:492
tmp
static guint32 * tmp
Definition: goom_core.cpp:31
MythObservable::addListener
void addListener(QObject *listener)
Add a listener to the observable.
Definition: mythobservable.cpp:38
HouseKeeperTask::Run
bool Run(void)
Definition: housekeeper.cpp:139
MythDate::fromSecsSinceEpoch
MBASE_PUBLIC QDateTime fromSecsSinceEpoch(uint seconds)
This function takes the number of seconds since the start of the epoch and returns a QDateTime with t...
Definition: mythdate.cpp:68
HouseKeeperTask::SetLastRun
virtual void SetLastRun(const QDateTime &last, bool successful=true)
Definition: housekeeper.cpp:304
PeriodicHouseKeeperTask::CalculateWindow
virtual void CalculateWindow(void)
Definition: housekeeper.cpp:337
MythCoreContext::SendEvent
void SendEvent(const MythEvent &event)
Definition: mythcorecontext.cpp:1540
DailyHouseKeeperTask::SetHourWindow
virtual void SetHourWindow(int min, int max)
Definition: housekeeper.cpp:485
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:178
DailyHouseKeeperTask::CalculateWindow
void CalculateWindow(void) override
Definition: housekeeper.cpp:466
HouseKeeperTask::GetLastRun
QDateTime GetLastRun(void)
Definition: housekeeper.h:55
HouseKeeper::m_queueLock
QMutex m_queueLock
Definition: housekeeper.h:170
HouseKeeperTask::HouseKeeperTask
HouseKeeperTask(const QString &dbTag, HouseKeeperScope scope=kHKGlobal, HouseKeeperStartup startup=kHKNormal)
Definition: housekeeper.cpp:100
PeriodicHouseKeeperTask
Modified HouseKeeperTask for tasks to be run at a regular interval.
Definition: housekeeper.h:85
HouseKeepingThread
Thread used to perform queued HouseKeeper tasks.
Definition: housekeeper.h:127
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:211
PeriodicHouseKeeperTask::m_period
int m_period
Definition: housekeeper.h:100
kHKRunImmediateOnStartup
@ kHKRunImmediateOnStartup
task is run during HouseKeeper startup
Definition: housekeeper.h:36
HouseKeeper::m_timer
QTimer * m_timer
Definition: housekeeper.h:167
MSqlQuery::isConnected
bool isConnected(void) const
Only updated once during object creation.
Definition: mythdbcon.h:135
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
PeriodicHouseKeeperTask::UpdateLastRun
QDateTime UpdateLastRun(const QDateTime &last, bool successful=true) override
Definition: housekeeper.cpp:360
HouseKeeperTask::GetTag
QString GetTag(void)
Definition: housekeeper.h:54
HouseKeeperScope
HouseKeeperScope
Definition: housekeeper.h:24
HouseKeeperTask::CheckStartup
bool CheckStartup(void)
Definition: housekeeper.cpp:129
HouseKeeperStartup
HouseKeeperStartup
Definition: housekeeper.h:33
HouseKeeper::~HouseKeeper
~HouseKeeper() override
Definition: housekeeper.cpp:584
HouseKeeperTask::m_lastSuccess
QDateTime m_lastSuccess
Definition: housekeeper.h:80
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:30
PeriodicHouseKeeperTask::m_windowElapsed
QPair< int, int > m_windowElapsed
Definition: housekeeper.h:103
HouseKeepingThread::m_idle
bool m_idle
Definition: housekeeper.h:141
HouseKeeperTask::m_running
bool m_running
Definition: housekeeper.h:77
HouseKeepingThread::m_parent
HouseKeeper * m_parent
Definition: housekeeper.h:143
HouseKeeper::m_taskMap
QMap< QString, HouseKeeperTask * > m_taskMap
Definition: housekeeper.h:172
HouseKeeperTask::QueryLastSuccess
QDateTime QueryLastSuccess(void)
Definition: housekeeper.cpp:174
PeriodicHouseKeeperTask::SetWindow
virtual void SetWindow(float min, float max)
Definition: housekeeper.cpp:353
PeriodicHouseKeeperTask::PastWindow
virtual bool PastWindow(const QDateTime &now)
Definition: housekeeper.cpp:432
HouseKeeper::StartThread
void StartThread(void)
Wake the primary run thread, or create a new one.
Definition: housekeeper.cpp:796
mythcorecontext.h
MythDate
Definition: mythdate.cpp:8
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:14
HouseKeeper::HouseKeeper
HouseKeeper(void)
Definition: housekeeper.cpp:576
PeriodicHouseKeeperTask::m_retry
int m_retry
Definition: housekeeper.h:101
kHKInst
@ kHKInst
task should run on every process e.g.
Definition: housekeeper.h:29
PeriodicHouseKeeperTask::m_currentProb
float m_currentProb
Definition: housekeeper.h:104
HouseKeepingThread::run
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: housekeeper.cpp:514
kHKRunOnStartup
@ kHKRunOnStartup
task is queued when HouseKeeper is started
Definition: housekeeper.h:35
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:859
PeriodicHouseKeeperTask::m_windowPercent
QPair< float, float > m_windowPercent
Definition: housekeeper.h:102
HouseKeeperTask::GetLastSuccess
QDateTime GetLastSuccess(void)
Definition: housekeeper.h:56
musicbrainzngs.caa.hostname
string hostname
Definition: caa.py:17
HouseKeepingThread::m_waitCondition
QWaitCondition m_waitCondition
Definition: housekeeper.h:145
HouseKeeperTask
Definition for a single task to be run by the HouseKeeper.
Definition: housekeeper.h:40
MThread::wait
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:305
HouseKeeperTask::DoRun
virtual bool DoRun(void)
Definition: housekeeper.h:66
HouseKeeperTask::CheckRun
bool CheckRun(const QDateTime &now)
Definition: housekeeper.cpp:110
DailyHouseKeeperTask::DailyHouseKeeperTask
DailyHouseKeeperTask(const QString &dbTag, HouseKeeperScope scope=kHKGlobal, HouseKeeperStartup startup=kHKNormal)
Definition: housekeeper.cpp:450
HouseKeeperTask::m_confirm
bool m_confirm
Definition: housekeeper.h:74
kHKLocal
@ kHKLocal
task should only run once per machine e.g.
Definition: housekeeper.h:27
HouseKeeperTask::m_scope
HouseKeeperScope m_scope
Definition: housekeeper.h:75
HouseKeeper::m_mapLock
QMutex m_mapLock
Definition: housekeeper.h:173
query
MSqlQuery query(MSqlQuery::InitCon())
MythObservable::removeListener
void removeListener(QObject *listener)
Remove a listener to the observable.
Definition: mythobservable.cpp:55
HouseKeeper::GetQueuedTask
HouseKeeperTask * GetQueuedTask(void)
Definition: housekeeper.cpp:657
HouseKeeper::Start
void Start(void)
Definition: housekeeper.cpp:672
HouseKeeperTask::m_dbTag
QString m_dbTag
Definition: housekeeper.h:73
HouseKeeperTask::m_lastRun
QDateTime m_lastRun
Definition: housekeeper.h:79
ReferenceCounter
General purpose reference counter.
Definition: referencecounter.h:27
HouseKeeperTask::ConfirmRun
bool ConfirmRun(void) const
Definition: housekeeper.h:48
kHKGlobal
@ kHKGlobal
task should only run once per cluster e.g.
Definition: housekeeper.h:25
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:808