diff --git a/src/ui/rpc/taskmanagerrpc.h b/src/ui/rpc/taskmanagerrpc.h index 83b57fc3..692e5b43 100644 --- a/src/ui/rpc/taskmanagerrpc.h +++ b/src/ui/rpc/taskmanagerrpc.h @@ -29,7 +29,7 @@ public slots: protected: void initializeTasks() override { } - void setupTimer(bool /*enabled*/ = true) override { } + void setupTimer(int /*secs*/) override { } }; #endif // TASKMANAGERRPC_H diff --git a/src/ui/task/taskinfo.cpp b/src/ui/task/taskinfo.cpp index a249ec6b..cf703a44 100644 --- a/src/ui/task/taskinfo.cpp +++ b/src/ui/task/taskinfo.cpp @@ -42,11 +42,6 @@ QString TaskInfo::title(TaskType type) } } -QDateTime TaskInfo::plannedRun() const -{ - return m_lastRun.addSecs(m_intervalHours * 60 * 60); -} - void TaskInfo::editFromVariant(const QVariant &v) { const TaskEditInfo task(v.toULongLong()); @@ -59,6 +54,19 @@ void TaskInfo::editFromVariant(const QVariant &v) setIntervalHours(task.intervalHours()); } +qint64 TaskInfo::secondsToRun(const QDateTime &now, bool isFirstRun) const +{ + if (isFirstRun && runOnStartup()) { + return delayStartup() ? retrySeconds() : 0; + } + + const qint64 delaySecs = (m_failedCount > 0) ? retrySeconds() : (intervalHours() * 60 * 60); + + const QDateTime plannedRun = m_lastRun.addSecs(delaySecs); + + return now.secsTo(plannedRun); +} + QString TaskInfo::typeToString(TaskInfo::TaskType type) { const QMetaEnum typeEnum = QMetaEnum::fromType(); @@ -123,8 +131,15 @@ void TaskInfo::handleFinished(bool success) return; setLastRun(DateUtil::now()); + if (success) { setLastSuccess(lastRun()); + + m_failedCount = 0; + } else { + if (++m_failedCount >= maxRetries()) { + m_failedCount = 0; + } } setRunning(false); diff --git a/src/ui/task/taskinfo.h b/src/ui/task/taskinfo.h index 66cdfe3e..7834d59f 100644 --- a/src/ui/task/taskinfo.h +++ b/src/ui/task/taskinfo.h @@ -67,8 +67,6 @@ public: QDateTime lastRun() const { return m_lastRun; } void setLastRun(const QDateTime &v) { m_lastRun = v; } - QDateTime plannedRun() const; - QDateTime lastSuccess() const { return m_lastSuccess; } void setLastSuccess(const QDateTime &v) { m_lastSuccess = v; } @@ -80,6 +78,8 @@ public: void editFromVariant(const QVariant &v); + qint64 secondsToRun(const QDateTime &now, bool isFirstRun) const; + virtual void initialize() { } static QString typeToString(TaskInfo::TaskType type); @@ -113,6 +113,7 @@ private: TaskType m_type = TypeNone; + quint8 m_failedCount = 0; // transient quint8 m_maxRetries = 0; quint16 m_retrySeconds = 0; quint16 m_intervalHours = TaskDefaultIntervalHours; diff --git a/src/ui/task/taskmanager.cpp b/src/ui/task/taskmanager.cpp index 0a734b9e..bcb6610d 100644 --- a/src/ui/task/taskmanager.cpp +++ b/src/ui/task/taskmanager.cpp @@ -9,6 +9,14 @@ #include "taskinfoupdatechecker.h" #include "taskinfozonedownloader.h" +namespace { + +constexpr int TIMER_STARTUP_SECONDS = 1; +constexpr int TIMER_DEFAULT_SECONDS = 5; +constexpr int TIMER_MAX_SECONDS = 24 * 60 * 60; // 1 day + +} + TaskManager::TaskManager(QObject *parent) : QObject(parent) { setupTasks(); @@ -44,7 +52,7 @@ void TaskManager::setUp() loadSettings(); initializeTasks(); - setupTimer(); + setupTimer(TIMER_STARTUP_SECONDS); connect(confManager, &ConfManager::confChanged, this, [&](bool onlyFlags, uint editedFlags) { if (onlyFlags && (editedFlags & FirewallConf::TaskEdited) == 0) @@ -61,12 +69,10 @@ void TaskManager::initializeTasks() } } -void TaskManager::setupTimer(bool enabled) +void TaskManager::setupTimer(int secs) { - if (enabled) { - const int msecs = m_isFirstRun ? 1000 // 1 second - : 5 * 60 * 1000; // 5 minutes - m_timer.start(msecs); + if (secs >= 0) { + m_timer.start(secs * 1000); } else { m_timer.stop(); } @@ -147,25 +153,37 @@ void TaskManager::handleTaskFinished(bool success) void TaskManager::runExpiredTasks() { const QDateTime now = DateUtil::now(); - bool enabledTaskExists = false; + qint64 sleepSecs = -1; for (TaskInfo *taskInfo : taskInfoList()) { - if (runExpiredTask(taskInfo, now)) { - enabledTaskExists = true; + qint64 secsToRun; + if (runExpiredTask(taskInfo, now, secsToRun)) { + sleepSecs = (sleepSecs < 0) ? secsToRun : qMin(sleepSecs, secsToRun); } } m_isFirstRun = false; - setupTimer(enabledTaskExists); + const int secs = qMin(sleepSecs, TIMER_MAX_SECONDS); + + setupTimer(secs); } -bool TaskManager::runExpiredTask(TaskInfo *taskInfo, const QDateTime &now) +bool TaskManager::runExpiredTask(TaskInfo *taskInfo, const QDateTime &now, qint64 &secsToRun) { if (!taskInfo->enabled()) return false; - if ((m_isFirstRun && taskInfo->runOnStartup()) || now >= taskInfo->plannedRun()) { + if (taskInfo->running()) { + secsToRun = TIMER_DEFAULT_SECONDS; + return true; + } + + secsToRun = taskInfo->secondsToRun(now, m_isFirstRun); + + if (secsToRun <= 1) { + secsToRun = TIMER_DEFAULT_SECONDS; + taskInfo->run(); } diff --git a/src/ui/task/taskmanager.h b/src/ui/task/taskmanager.h index a8a37245..f6f6c565 100644 --- a/src/ui/task/taskmanager.h +++ b/src/ui/task/taskmanager.h @@ -59,7 +59,7 @@ private slots: protected: virtual void initializeTasks(); - virtual void setupTimer(bool enabled = true); + virtual void setupTimer(int secs); TaskInfo *taskInfoByType(qint8 taskType) const; @@ -68,7 +68,7 @@ private: void appendTaskInfo(TaskInfo *taskInfo); - bool runExpiredTask(TaskInfo *taskInfo, const QDateTime &now); + bool runExpiredTask(TaskInfo *taskInfo, const QDateTime &now, qint64 &secsToRun); private: bool m_isFirstRun = true;