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