Go to the documentation of this file.
55 #include <QMutexLocker>
110 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Checking to run %1").arg(
GetTag()));
139 LOG(VB_GENERAL, LOG_INFO, QString(
"Running HouseKeeperTask '%1'.")
144 LOG(VB_GENERAL, LOG_WARNING, QString(
"HouseKeeperTask '%1' already "
145 "running. Refusing to run concurrently").arg(
m_dbTag));
154 LOG(VB_GENERAL, LOG_INFO, QString(
"HouseKeeperTask '%1' Failed.")
159 LOG(VB_GENERAL, LOG_INFO,
160 QString(
"HouseKeeperTask '%1' Finished Successfully.")
193 query.
prepare(
"SELECT lastrun,lastsuccess FROM housekeeping"
195 " AND hostname IS NULL");
199 query.
prepare(
"SELECT lastrun,lastsuccess FROM housekeeping"
201 " AND hostname = :HOST");
236 query.
prepare(
"INSERT INTO housekeeping"
237 " (tag, lastrun, lastsuccess)"
238 " VALUES (:TAG, :TIME, :STIME)");
242 query.
prepare(
"INSERT INTO housekeeping"
243 " (tag, hostname, lastrun, lastsuccess)"
244 " VALUES (:TAG, :HOST, :TIME, :STIME)");
253 query.
prepare(
"UPDATE housekeeping SET lastrun=:TIME,"
254 " lastsuccess=:STIME"
256 " AND hostname IS NULL");
260 query.
prepare(
"UPDATE housekeeping SET lastrun=:TIME,"
261 " lastsuccess=:STIME"
263 " AND hostname = :HOST");
269 LOG(VB_GENERAL, LOG_DEBUG,
270 QString(
"Updating global run time for %1").arg(
m_dbTag));
274 LOG(VB_GENERAL, LOG_DEBUG,
275 QString(
"Updating local run time for %1").arg(
m_dbTag));
290 msg = QString(
"HOUSE_KEEPER_SUCCESSFUL %1 %2 %3");
292 msg = QString(
"HOUSE_KEEPER_RUNNING %1 %2 %3");
325 std::chrono::seconds period,
float min,
float max, std::chrono::seconds retry,
328 m_windowPercent(min, max), m_currentProb(1.0)
337 std::chrono::seconds period =
m_period;
374 auto elapsed = std::chrono::seconds(
GetLastRun().secsTo(now));
389 double prob = 1.0 - (duration_cast<floatsecs>(elapsed -
m_windowElapsed.first) /
405 bool res = (rand() > (int)(prob2 *
static_cast<double>(RAND_MAX)));
418 auto elapsed = std::chrono::seconds(
GetLastRun().secsTo(now));
449 m_windowHour(0h, 23h)
455 std::chrono::hours minhour, std::chrono::hours maxhour,
458 m_windowHour(minhour, maxhour)
478 LOG(VB_GENERAL, LOG_DEBUG, QString(
"%1 Run window between %2 - %3.")
495 auto hour = std::chrono::hours(now.time().hour());
626 QMap<QString,HouseKeeperTask*>::iterator it =
m_taskMap.begin();
638 QString tag = task->
GetTag();
642 LOG(VB_GENERAL, LOG_ERR,
643 QString(
"HouseKeeperTask '%1' already registered. "
644 "Rejecting duplicate.").arg(tag));
648 LOG(VB_GENERAL, LOG_INFO,
649 QString(
"Registering HouseKeeperTask '%1'.").arg(tag));
679 query.
prepare(
"SELECT tag,lastrun"
681 " WHERE hostname = :HOST"
682 " OR hostname IS NULL");
692 QString tag = query.
value(0).toString();
704 if ((*it)->CheckImmediate())
707 (*it)->UpdateLastRun();
710 else if ((*it)->CheckStartup())
713 LOG(VB_GENERAL, LOG_INFO,
714 QString(
"Queueing HouseKeeperTask '%1'.").arg(it.key()));
721 LOG(VB_GENERAL, LOG_INFO,
"Starting HouseKeeper.");
728 LOG(VB_GENERAL, LOG_DEBUG,
"Running HouseKeeper.");
735 if ((*it)->CheckRun(now))
738 LOG(VB_GENERAL, LOG_INFO,
739 QString(
"Queueing HouseKeeperTask '%1'.").arg(it.key()));
760 if ((*it)->isRunning())
772 LOG(VB_GENERAL, LOG_DEBUG,
773 QString(
"Discarded HouseKeepingThreads have completed and "
774 "been deleted. Current count %1 -> %2.")
775 .arg(count1).arg(count2));
801 LOG(VB_GENERAL, LOG_DEBUG,
"Running initial HouseKeepingThread.");
812 LOG(VB_GENERAL, LOG_DEBUG,
813 QString(
"Current HouseKeepingThread is delayed on task, "
814 "spawning replacement. Current count %1.")
825 LOG(VB_GENERAL, LOG_DEBUG,
"Waking HouseKeepingThread.");
837 if ((me->Message().left(20) ==
"HOUSE_KEEPER_RUNNING") ||
838 (me->Message().left(23) ==
"HOUSE_KEEPER_SUCCESSFUL"))
840 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
841 QStringList tokens = me->
Message()
842 .split(
" ", QString::SkipEmptyParts);
844 QStringList tokens = me->Message()
845 .split(
" ", Qt::SkipEmptyParts);
847 if (tokens.size() != 4)
851 QString tag = tokens[2];
853 bool successful = me->Message().contains(
"SUCCESSFUL");
865 m_taskMap[tag]->SetLastRun(last, successful);
This decrements the reference on destruction.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
QSqlQuery wrapper that fetches a DB connection from the connection pool.
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
static Type MythEventMessage
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
HouseKeeperStartup m_startup
std::chrono::seconds m_retry
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
QList< HouseKeepingThread * > m_threadList
void SetLastRun(const QDateTime &last, bool successful=true) override
virtual bool InWindow(const QDateTime &now)
bool CheckImmediate(void)
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
virtual bool DoCheckRun(const QDateTime &)
QDateTime QueryLastRun(void)
This class is used as a container for messages.
static constexpr T chronomult(T duration, double f)
Multiply a duration by a float, returning a duration.
QVariant value(int i) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
bool DoCheckRun(const QDateTime &now) override
QQueue< HouseKeeperTask * > m_taskQueue
void customEvent(QEvent *e) override
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
void RegisterTask(HouseKeeperTask *task)
QDateTime UpdateLastRun(bool successful=true)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
const QString & Message() const
bool InWindow(const QDateTime &now) override
void addListener(QObject *listener)
Add a listener to the observable.
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...
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)
virtual void SetLastRun(const QDateTime &last, bool successful=true)
virtual void CalculateWindow(void)
void SendEvent(const MythEvent &event)
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
static void DBError(const QString &where, const MSqlQuery &query)
virtual void SetHourWindow(std::chrono::hours min, std::chrono::hours max)
void CalculateWindow(void) override
QDateTime GetLastRun(void)
HouseKeeperTask(const QString &dbTag, HouseKeeperScope scope=kHKGlobal, HouseKeeperStartup startup=kHKNormal)
Modified HouseKeeperTask for tasks to be run at a regular interval.
Thread used to perform queued HouseKeeper tasks.
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
@ kHKRunImmediateOnStartup
task is run during HouseKeeper startup
bool isConnected(void) const
Only updated once during object creation.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QDateTime UpdateLastRun(const QDateTime &last, bool successful=true) override
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QPair< std::chrono::seconds, std::chrono::seconds > m_windowElapsed
QMap< QString, HouseKeeperTask * > m_taskMap
QPair< std::chrono::hours, std::chrono::hours > m_windowHour
QDateTime QueryLastSuccess(void)
virtual void SetWindow(float min, float max)
virtual bool PastWindow(const QDateTime &now)
void StartThread(void)
Wake the primary run thread, or create a new one.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
std::chrono::seconds m_period
@ kHKInst
task should run on every process e.g.
void run(void) override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
@ kHKRunOnStartup
task is queued when HouseKeeper is started
QString GetHostName(void)
QPair< float, float > m_windowPercent
QDateTime GetLastSuccess(void)
QWaitCondition m_waitCondition
Definition for a single task to be run by the HouseKeeper.
bool CheckRun(const QDateTime &now)
DailyHouseKeeperTask(const QString &dbTag, HouseKeeperScope scope=kHKGlobal, HouseKeeperStartup startup=kHKNormal)
@ kHKLocal
task should only run once per machine e.g.
void removeListener(QObject *listener)
Remove a listener to the observable.
HouseKeeperTask * GetQueuedTask(void)
General purpose reference counter.
bool ConfirmRun(void) const
@ kHKGlobal
task should only run once per cluster e.g.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.