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 
53 #include <QMutexLocker>
54 #include <utility>
55 
56 #include "mythevent.h"
57 #include "mythdbcon.h"
58 #include "housekeeper.h"
59 #include "mythcorecontext.h"
60 
99  ReferenceCounter(dbTag), m_dbTag(dbTag), m_scope(scope),
100  m_startup(startup),
101  m_lastRun(MythDate::fromSecsSinceEpoch(0)),
102  m_lastSuccess(MythDate::fromSecsSinceEpoch(0)),
103  m_lastUpdate(MythDate::fromSecsSinceEpoch(0))
104 {
105 }
106 
107 bool HouseKeeperTask::CheckRun(const QDateTime& now)
108 {
109  LOG(VB_GENERAL, LOG_DEBUG, QString("Checking to run %1").arg(GetTag()));
110  bool check = false;
111  if (!m_confirm && !m_running && (check = DoCheckRun(now)))
112  {
113  // if m_confirm is already set, the task is already in the queue
114  // and should not be queued a second time
115  m_confirm = true;
116  }
117  return check;
118 }
119 
121 {
122  return ((m_startup == kHKRunImmediateOnStartup) &&
124 }
125 
127 {
129  {
130  m_confirm = true;
131  return true;
132  }
133  return false;
134 }
135 
137 {
138  LOG(VB_GENERAL, LOG_INFO, QString("Running HouseKeeperTask '%1'.")
139  .arg(m_dbTag));
140  if (m_running)
141  {
142  // something else is already running me, bail out
143  LOG(VB_GENERAL, LOG_WARNING, QString("HouseKeeperTask '%1' already "
144  "running. Refusing to run concurrently").arg(m_dbTag));
145  return false;
146  }
147 
148  m_running = true;
149  bool res = DoRun();
150  m_running = false;
151  if (!res)
152  {
153  LOG(VB_GENERAL, LOG_INFO, QString("HouseKeeperTask '%1' Failed.")
154  .arg(m_dbTag));
155  }
156  else
157  {
158  LOG(VB_GENERAL, LOG_INFO,
159  QString("HouseKeeperTask '%1' Finished Successfully.")
160  .arg(m_dbTag));
161  }
162  return res;
163 }
164 
166 {
167  QueryLast();
168  return m_lastRun;
169 }
170 
172 {
173  QueryLast();
174  return m_lastRun;
175 }
176 
178 {
179  if (m_scope != kHKInst)
180  {
181  if (m_lastUpdate.addSecs(30) > MythDate::current())
182  // just to cut down on unnecessary queries
183  return;
184 
186 
189 
190  if (m_scope == kHKGlobal)
191  {
192  query.prepare("SELECT lastrun,lastsuccess FROM housekeeping"
193  " WHERE tag = :TAG"
194  " AND hostname IS NULL");
195  }
196  else
197  {
198  query.prepare("SELECT lastrun,lastsuccess FROM housekeeping"
199  " WHERE tag = :TAG"
200  " AND hostname = :HOST");
202  }
203 
204  query.bindValue(":TAG", m_dbTag);
205 
206  if (query.exec() && query.next())
207  {
208  m_lastRun = MythDate::as_utc(query.value(0).toDateTime());
209  m_lastSuccess = MythDate::as_utc(query.value(1).toDateTime());
210  }
211  }
212 
214 }
215 
216 QDateTime HouseKeeperTask::UpdateLastRun(const QDateTime& last, bool successful)
217 {
218  m_lastRun = last;
219  if (successful)
220  m_lastSuccess = last;
221  m_confirm = false;
222 
223  if (m_scope != kHKInst)
224  {
226  if (!query.isConnected())
227  return last;
228 
230  {
231  // not previously set, perform insert
232 
233  if (m_scope == kHKGlobal)
234  {
235  query.prepare("INSERT INTO housekeeping"
236  " (tag, lastrun, lastsuccess)"
237  " VALUES (:TAG, :TIME, :STIME)");
238  }
239  else
240  {
241  query.prepare("INSERT INTO housekeeping"
242  " (tag, hostname, lastrun, lastsuccess)"
243  " VALUES (:TAG, :HOST, :TIME, :STIME)");
244  }
245  }
246  else
247  {
248  // previously set, perform update
249 
250  if (m_scope == kHKGlobal)
251  {
252  query.prepare("UPDATE housekeeping SET lastrun=:TIME,"
253  " lastsuccess=:STIME"
254  " WHERE tag = :TAG"
255  " AND hostname IS NULL");
256  }
257  else
258  {
259  query.prepare("UPDATE housekeeping SET lastrun=:TIME,"
260  " lastsuccess=:STIME"
261  " WHERE tag = :TAG"
262  " AND hostname = :HOST");
263  }
264  }
265 
266  if (m_scope == kHKGlobal)
267  {
268  LOG(VB_GENERAL, LOG_DEBUG,
269  QString("Updating global run time for %1").arg(m_dbTag));
270  }
271  else
272  {
273  LOG(VB_GENERAL, LOG_DEBUG,
274  QString("Updating local run time for %1").arg(m_dbTag));
275  }
276 
277  if (m_scope == kHKLocal)
279  query.bindValue(":TAG", m_dbTag);
282 
283  if (!query.exec())
284  MythDB::DBError("HouseKeeperTask::updateLastRun", query);
285  }
286 
287  QString msg;
288  if (successful)
289  msg = QString("HOUSE_KEEPER_SUCCESSFUL %1 %2 %3");
290  else
291  msg = QString("HOUSE_KEEPER_RUNNING %1 %2 %3");
292  msg = msg.arg(gCoreContext->GetHostName())
293  .arg(m_dbTag)
297 
298  return last;
299 }
300 
301 void HouseKeeperTask::SetLastRun(const QDateTime &last, bool successful)
302 {
303  m_lastRun = last;
304  if (successful)
305  m_lastSuccess = last;
306 
308 }
309 
324  int period, float min, float max, int retry,
326  HouseKeeperTask(dbTag, scope, startup), m_period(period), m_retry(retry),
327  m_windowPercent(min, max), m_currentProb(1.0)
328 {
330  if (m_retry == 0)
331  m_retry = m_period;
332 }
333 
335 {
336  int period = m_period;
337  if (GetLastRun() > GetLastSuccess())
338  {
339  // last attempt was not successful
340  // try shortened period
341  period = m_retry;
342  }
343 
344  m_windowElapsed.first =
345  (uint32_t)((float)period * m_windowPercent.first);
346  m_windowElapsed.second =
347  (uint32_t)((float)period * m_windowPercent.second);
348 }
349 
350 void PeriodicHouseKeeperTask::SetWindow(float min, float max)
351 {
352  m_windowPercent.first = min;
353  m_windowPercent.second = max;
354  CalculateWindow();
355 }
356 
357 QDateTime PeriodicHouseKeeperTask::UpdateLastRun(const QDateTime& last,
358  bool successful)
359 {
360  QDateTime res = HouseKeeperTask::UpdateLastRun(last, successful);
361  CalculateWindow();
362  m_currentProb = 1.0;
363  return res;
364 }
365 
366 void PeriodicHouseKeeperTask::SetLastRun(const QDateTime& last, bool successful)
367 {
368  HouseKeeperTask::SetLastRun(last, successful);
369  CalculateWindow();
370  m_currentProb = 1.0;
371 }
372 
373 bool PeriodicHouseKeeperTask::DoCheckRun(const QDateTime& now)
374 {
375  int elapsed = GetLastRun().secsTo(now);
376 
377  if (elapsed < 0)
378  // something bad has happened. let's just move along
379  return false;
380 
381  if (elapsed < m_windowElapsed.first)
382  // insufficient time elapsed to test
383  return false;
384  if (elapsed > m_windowElapsed.second)
385  // too much time has passed. force run
386  return true;
387 
388  // calculate probability that task should not have yet run
389  // it's backwards, but it makes the math simplier
390  float prob = 1.0F - ((float)(elapsed - m_windowElapsed.first) /
391  (float)(m_windowElapsed.second - m_windowElapsed.first));
392  if (m_currentProb < prob)
393  // more bad stuff
394  return false;
395 
396  // calculate current probability to achieve overall probability
397  // this should be nearly one
398  float prob2 = prob/m_currentProb;
399  // so rand() should have to return nearly RAND_MAX to get a positive
400  // remember, this is computing the probability that up to this point, one
401  // of these tests has returned positive, so each individual test has
402  // a necessarily low probability
403  //
404  // Pseudo-random is good enough. Don't need a true random.
405  // NOLINTNEXTLINE(cert-msc30-c,cert-msc50-cpp)
406  bool res = (rand() > (int)(prob2 * static_cast<float>(RAND_MAX)));
407  m_currentProb = prob;
408 // if (res)
409 // LOG(VB_GENERAL, LOG_DEBUG, QString("%1 will run: this=%2; total=%3")
410 // .arg(GetTag()).arg(1-prob2).arg(1-prob));
411 // else
412 // LOG(VB_GENERAL, LOG_DEBUG, QString("%1 will not run: this=%2; total=%3")
413 // .arg(GetTag()).arg(1-prob2).arg(1-prob));
414  return res;
415 }
416 
417 bool PeriodicHouseKeeperTask::InWindow(const QDateTime& now)
418 {
419  int elapsed = GetLastRun().secsTo(now);
420 
421  if (elapsed < 0)
422  // something bad has happened. let's just move along
423  return false;
424 
425  return (elapsed > m_windowElapsed.first) &&
426  (elapsed < m_windowElapsed.second);
427 }
428 
429 bool PeriodicHouseKeeperTask::PastWindow(const QDateTime &now)
430 {
431  return GetLastRun().secsTo(now) > m_windowElapsed.second;
432 }
433 
449  PeriodicHouseKeeperTask(dbTag, 86400, .5, 1.5, 0, scope, startup),
450  m_windowHour(0, 23)
451 {
453 }
454 
455 DailyHouseKeeperTask::DailyHouseKeeperTask(const QString &dbTag, int minhour,
456  int maxhour, HouseKeeperScope scope, HouseKeeperStartup startup) :
457  PeriodicHouseKeeperTask(dbTag, 86400, .5, 1.5, 0, scope, startup),
458  m_windowHour(minhour, maxhour)
459 {
461 }
462 
464 {
466  QDate date = GetLastRun().addDays(1).date();
467 
468  QDateTime tmp = QDateTime(date, QTime(m_windowHour.first, 0));
469  if (GetLastRun().addSecs(m_windowElapsed.first) < tmp)
470  m_windowElapsed.first = GetLastRun().secsTo(tmp);
471 
472  tmp = QDateTime(date, QTime(m_windowHour.second, 30));
473  // we want to make sure this gets run before the end of the day
474  // so add a 30 minute buffer prior to the end of the window
475  if (GetLastRun().addSecs(m_windowElapsed.second) > tmp)
476  m_windowElapsed.second = GetLastRun().secsTo(tmp);
477 
478  LOG(VB_GENERAL, LOG_DEBUG, QString("%1 Run window between %2 - %3.")
479  .arg(GetTag()).arg(m_windowElapsed.first).arg(m_windowElapsed.second));
480 }
481 
483 {
484  m_windowHour.first = min;
485  m_windowHour.second = max;
486  CalculateWindow();
487 }
488 
489 bool DailyHouseKeeperTask::InWindow(const QDateTime& now)
490 {
492  // parent says we're in the window
493  return true;
494 
495  int hour = now.time().hour();
496  // true if we've missed the window, but we're within our time constraints
497  return PastWindow(now) && (m_windowHour.first <= hour)
498  && (m_windowHour.second > hour);
499 }
500 
512 {
513  RunProlog();
514  m_waitMutex.lock();
515  HouseKeeperTask *task = nullptr;
516 
517  while (m_keepRunning)
518  {
519  m_idle = false;
520 
521  while ((task = m_parent->GetQueuedTask()))
522  {
523  // pull task from housekeeper and process it
524  ReferenceLocker rlock(task);
525 
526  if (!task->ConfirmRun())
527  {
528  // something else has caused the lastrun time to
529  // change since this was requested to run. abort.
530  task = nullptr;
531  continue;
532  }
533 
534  task->UpdateLastRun(false);
535  if (task->Run())
536  task->UpdateLastRun(task->GetLastRun(), true);
537  task = nullptr;
538 
539  if (!m_keepRunning)
540  // thread has been discarded, don't try to start another task
541  break;
542  }
543 
544  m_idle = true;
545 
546  if (!m_keepRunning)
547  // short out rather than potentially hitting another sleep cycle
548  break;
549 
551  }
552 
553  m_waitMutex.unlock();
554  RunEpilog();
555 }
556 
574 {
575  m_timer = new QTimer(this);
576  connect(m_timer, SIGNAL(timeout()), this, SLOT(Run()));
577  m_timer->setInterval(60000);
578  m_timer->setSingleShot(false);
579 }
580 
582 {
584 
585  if (m_timer)
586  {
587  m_timer->stop();
588  disconnect(m_timer);
589  delete m_timer;
590  m_timer = nullptr;
591  }
592 
593  {
594  // remove anything from the queue first, so it does not start
595  QMutexLocker queueLock(&m_queueLock);
596  while (!m_taskQueue.isEmpty())
597  m_taskQueue.takeFirst()->DecrRef();
598  }
599 
600  {
601  // issue a terminate call to any long-running tasks
602  // this is just a noop unless overwritten by a subclass
603  QMutexLocker mapLock(&m_mapLock);
604  for (auto *it : qAsConst(m_taskMap))
605  it->Terminate();
606  }
607 
608  if (!m_threadList.isEmpty())
609  {
610  QMutexLocker threadLock(&m_threadLock);
611  // tell primary thread to self-terminate and wake it
612  m_threadList.first()->Discard();
613  m_threadList.first()->Wake();
614  // wait for any remaining threads to self-terminate and close
615  while (!m_threadList.isEmpty())
616  {
617  HouseKeepingThread *thread = m_threadList.takeFirst();
618  thread->wait();
619  delete thread;
620  }
621  }
622 
623  {
624  // unload any registered tasks
625  QMutexLocker mapLock(&m_mapLock);
626  QMap<QString,HouseKeeperTask*>::iterator it = m_taskMap.begin();
627  while (it != m_taskMap.end())
628  {
629  (*it)->DecrRef();
630  it = m_taskMap.erase(it);
631  }
632  }
633 }
634 
636 {
637  QMutexLocker mapLock(&m_mapLock);
638  QString tag = task->GetTag();
639  if (m_taskMap.contains(tag))
640  {
641  task->DecrRef();
642  LOG(VB_GENERAL, LOG_ERR,
643  QString("HouseKeeperTask '%1' already registered. "
644  "Rejecting duplicate.").arg(tag));
645  }
646  else
647  {
648  LOG(VB_GENERAL, LOG_INFO,
649  QString("Registering HouseKeeperTask '%1'.").arg(tag));
650  m_taskMap.insert(tag, task);
651  }
652 }
653 
655 {
656  QMutexLocker queueLock(&m_queueLock);
657  HouseKeeperTask *task = nullptr;
658 
659  if (!m_taskQueue.isEmpty())
660  {
661  task = m_taskQueue.dequeue();
662  }
663 
664  // returning nullptr tells the thread that the queue is empty and
665  // to go into standby
666  return task;
667 }
668 
670 {
671  // no need to be fine grained, nothing else should be accessing this map
672  QMutexLocker mapLock(&m_mapLock);
673 
674  if (m_timer->isActive())
675  // Start() should only be called once
676  return;
677 
679  query.prepare("SELECT tag,lastrun"
680  " FROM housekeeping"
681  " WHERE hostname = :HOST"
682  " OR hostname IS NULL");
684 
685  if (!query.exec())
686  MythDB::DBError("HouseKeeper::Run", query);
687  else
688  {
689  while (query.next())
690  {
691  // loop through housekeeping table and load last run timestamps
692  QString tag = query.value(0).toString();
693  QDateTime lastrun = MythDate::as_utc(query.value(1).toDateTime());
694 
695  if (m_taskMap.contains(tag))
696  m_taskMap[tag]->SetLastRun(lastrun);
697  }
698  }
699 
700  gCoreContext->addListener(this);
701 
702  QMap<QString,HouseKeeperTask*>::const_iterator it;
703  for (it = m_taskMap.begin(); it != m_taskMap.end(); ++it)
704  {
705  if ((*it)->CheckImmediate())
706  {
707  // run any tasks marked for immediate operation in-thread
708  (*it)->UpdateLastRun();
709  (*it)->Run();
710  }
711  else if ((*it)->CheckStartup())
712  {
713  // queue any tasks marked for startup
714  LOG(VB_GENERAL, LOG_INFO,
715  QString("Queueing HouseKeeperTask '%1'.").arg(it.key()));
716  QMutexLocker queueLock(&m_queueLock);
717  (*it)->IncrRef();
718  m_taskQueue.enqueue(*it);
719  }
720  }
721 
722  LOG(VB_GENERAL, LOG_INFO, "Starting HouseKeeper.");
723 
724  m_timer->start();
725 }
726 
728 {
729  LOG(VB_GENERAL, LOG_DEBUG, "Running HouseKeeper.");
730 
731  QDateTime now = MythDate::current();
732 
733  QMutexLocker mapLock(&m_mapLock);
734  for (auto it = m_taskMap.begin(); it != m_taskMap.end(); ++it)
735  {
736  if ((*it)->CheckRun(now))
737  {
738  // check if any tasks are ready to run, and add to queue
739  LOG(VB_GENERAL, LOG_INFO,
740  QString("Queueing HouseKeeperTask '%1'.").arg(it.key()));
741  QMutexLocker queueLock(&m_queueLock);
742  (*it)->IncrRef();
743  m_taskQueue.enqueue(*it);
744  }
745  }
746 
747  if (!m_taskQueue.isEmpty())
748  StartThread();
749 
750  if (m_threadList.size() > 1)
751  {
752  // spent threads exist in the thread list
753  // check to see if any have finished up their task and terminated
754  QMutexLocker threadLock(&m_threadLock);
755  int count1 = m_threadList.size();
756 
757  auto it = m_threadList.begin();
758  ++it; // skip the primary thread
759  while (it != m_threadList.end())
760  {
761  if ((*it)->isRunning())
762  ++it;
763  else
764  {
765  delete *it;
766  it = m_threadList.erase(it);
767  }
768  }
769 
770  int count2 = m_threadList.size();
771  if (count1 > count2)
772  {
773  LOG(VB_GENERAL, LOG_DEBUG,
774  QString("Discarded HouseKeepingThreads have completed and "
775  "been deleted. Current count %1 -> %2.")
776  .arg(count1).arg(count2));
777  }
778  }
779 }
780 
795 {
796  QMutexLocker threadLock(&m_threadLock);
797 
798  if (m_threadList.isEmpty())
799  {
800  // we're running for the first time
801  // start up a new thread
802  LOG(VB_GENERAL, LOG_DEBUG, "Running initial HouseKeepingThread.");
803  auto *thread = new HouseKeepingThread(this);
804  m_threadList.append(thread);
805  thread->start();
806  }
807 
808  else if (!m_threadList.first()->isIdle())
809  {
810  // the old thread is still off processing something
811  // discard it and start a new one because we have more stuff
812  // that wants to run
813  LOG(VB_GENERAL, LOG_DEBUG,
814  QString("Current HouseKeepingThread is delayed on task, "
815  "spawning replacement. Current count %1.")
816  .arg(m_threadList.size()));
817  m_threadList.first()->Discard();
818  auto *thread = new HouseKeepingThread(this);
819  m_threadList.prepend(thread);
820  thread->start();
821  }
822 
823  else
824  {
825  // the old thread is idle, so just wake it for processing
826  LOG(VB_GENERAL, LOG_DEBUG, "Waking HouseKeepingThread.");
827  m_threadList.first()->Wake();
828  }
829 }
830 
832 {
833  if (e->type() == MythEvent::MythEventMessage)
834  {
835  auto *me = dynamic_cast<MythEvent*>(e);
836  if (me == nullptr)
837  return;
838  if ((me->Message().left(20) == "HOUSE_KEEPER_RUNNING") ||
839  (me->Message().left(23) == "HOUSE_KEEPER_SUCCESSFUL"))
840  {
841 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
842  QStringList tokens = me->Message()
843  .split(" ", QString::SkipEmptyParts);
844 #else
845  QStringList tokens = me->Message()
846  .split(" ", Qt::SkipEmptyParts);
847 #endif
848  if (tokens.size() != 4)
849  return;
850 
851  QString hostname = tokens[1];
852  QString tag = tokens[2];
853  QDateTime last = MythDate::fromString(tokens[3]);
854  bool successful = me->Message().contains("SUCCESSFUL");
855 
856  QMutexLocker mapLock(&m_mapLock);
857  if (m_taskMap.contains(tag))
858  {
859  if ((m_taskMap[tag]->GetScope() == kHKGlobal) ||
860  ((m_taskMap[tag]->GetScope() == kHKLocal) &&
862  {
863  // task being run in the same scope as us.
864  // update the run time so we don't attempt to run
865  // it ourselves
866  m_taskMap[tag]->SetLastRun(last, successful);
867  }
868  }
869  }
870  }
871 }
ReferenceLocker
This decrements the reference on destruction.
Definition: referencecounter.h:66
HouseKeeperTask::QueryLast
void QueryLast(void)
Definition: housekeeper.cpp:177
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:125
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1417
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:366
housekeeper.h
PeriodicHouseKeeperTask::InWindow
virtual bool InWindow(const QDateTime &now)
Definition: housekeeper.cpp:417
HouseKeeperTask::CheckImmediate
bool CheckImmediate(void)
Definition: housekeeper.cpp:120
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:165
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
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:373
HouseKeeper::m_taskQueue
QQueue< HouseKeeperTask * > m_taskQueue
Definition: housekeeper.h:169
HouseKeeper::customEvent
void customEvent(QEvent *e) override
Definition: housekeeper.cpp:831
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:202
HouseKeeper::RegisterTask
void RegisterTask(HouseKeeperTask *task)
Definition: housekeeper.cpp:635
startup
static int startup()
Definition: mythtv/programs/mythshutdown/main.cpp:772
HouseKeeperTask::m_lastUpdate
QDateTime m_lastUpdate
Definition: housekeeper.h:81
HouseKeeper::Run
void Run(void)
Definition: housekeeper.cpp:727
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:323
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:489
tmp
static guint32 * tmp
Definition: goom_core.cpp:30
MythObservable::addListener
void addListener(QObject *listener)
Add a listener to the observable.
Definition: mythobservable.cpp:38
HouseKeeperTask::Run
bool Run(void)
Definition: housekeeper.cpp:136
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:301
PeriodicHouseKeeperTask::CalculateWindow
virtual void CalculateWindow(void)
Definition: housekeeper.cpp:334
MythCoreContext::SendEvent
void SendEvent(const MythEvent &event)
Definition: mythcorecontext.cpp:1512
DailyHouseKeeperTask::SetHourWindow
virtual void SetHourWindow(int min, int max)
Definition: housekeeper.cpp:482
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:179
DailyHouseKeeperTask::CalculateWindow
void CalculateWindow(void) override
Definition: housekeeper.cpp:463
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:97
PeriodicHouseKeeperTask
Modified HouseKeeperTask for tasks to be run at a regular interval.
Definition: housekeeper.h:84
HouseKeepingThread
Thread used to perform queued HouseKeeper tasks.
Definition: housekeeper.h:126
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:215
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:57
PeriodicHouseKeeperTask::UpdateLastRun
QDateTime UpdateLastRun(const QDateTime &last, bool successful=true) override
Definition: housekeeper.cpp:357
HouseKeeperTask::GetTag
QString GetTag(void)
Definition: housekeeper.h:54
HouseKeeperScope
HouseKeeperScope
Definition: housekeeper.h:24
HouseKeeperTask::CheckStartup
bool CheckStartup(void)
Definition: housekeeper.cpp:126
HouseKeeperStartup
HouseKeeperStartup
Definition: housekeeper.h:33
HouseKeeper::~HouseKeeper
~HouseKeeper() override
Definition: housekeeper.cpp:581
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:171
PeriodicHouseKeeperTask::SetWindow
virtual void SetWindow(float min, float max)
Definition: housekeeper.cpp:350
PeriodicHouseKeeperTask::PastWindow
virtual bool PastWindow(const QDateTime &now)
Definition: housekeeper.cpp:429
HouseKeeper::StartThread
void StartThread(void)
Wake the primary run thread, or create a new one.
Definition: housekeeper.cpp:794
mythcorecontext.h
MythDate
Definition: mythdate.cpp:7
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:573
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:511
kHKRunOnStartup
@ kHKRunOnStartup
task is queued when HouseKeeper is started
Definition: housekeeper.h:35
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:841
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:39
MThread::wait
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:309
HouseKeeperTask::DoRun
virtual bool DoRun(void)
Definition: housekeeper.h:66
HouseKeeperTask::CheckRun
bool CheckRun(const QDateTime &now)
Definition: housekeeper.cpp:107
DailyHouseKeeperTask::DailyHouseKeeperTask
DailyHouseKeeperTask(const QString &dbTag, HouseKeeperScope scope=kHKGlobal, HouseKeeperStartup startup=kHKNormal)
Definition: housekeeper.cpp:447
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:654
HouseKeeper::Start
void Start(void)
Definition: housekeeper.cpp:669
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:26
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