From c5f0c035fe3bee0ec38d1f8718e06565a4be0a57 Mon Sep 17 00:00:00 2001 From: slava Date: Mon, 1 Jun 2026 00:27:43 +0500 Subject: [PATCH] Adjust watchdog timer for `FETCH_TRANSACTIONS` to 10 minutes; optimize scroll behavior in `GetLastTransactionsScript`. --- .../dushanbe/GetLastTransactionsScript.cpp | 23 +++++++++++++++++++ services/EventHandler.cpp | 14 +++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/android/dushanbe/GetLastTransactionsScript.cpp b/android/dushanbe/GetLastTransactionsScript.cpp index 566e3a4..08be599 100644 --- a/android/dushanbe/GetLastTransactionsScript.cpp +++ b/android/dushanbe/GetLastTransactionsScript.cpp @@ -978,6 +978,29 @@ bool GetLastTransactionsScript::searchOne(const DeviceInfo &device, int accountI return true; // успех — транзакция найдена и отдана через transactionParsed } + // Окно поиска — только "сегодня + вчера". Список Выписки идёт сверху-вниз + // от новых к старым; группы-даты на текущем экране собраны в groupDates. + // Как только самая свежая видимая дата уже старше вчерашнего дня — значит + // окно today+yesterday полностью проскроллено, дальше только старая история. + // Прекращаем скролл (целевой транзакции в окне нет), вместо того чтобы + // листать до упора и упереться в watchdog-таймаут. + { + const QDate cutoff = todayLocal.addDays(-1); // вчера + QDate newestVisible; + for (const QString &gd : groupDates) { + const QDate d = QDate::fromString(gd, "dd.MM.yyyy"); + if (d.isValid() && (newestVisible.isNull() || d > newestVisible)) + newestVisible = d; + } + if (newestVisible.isValid() && newestVisible < cutoff) { + qDebug() << "[Dushanbe::GetLastTransactions] Past today+yesterday window" + " (newest visible=" << newestVisible.toString("dd.MM.yyyy") + << "< cutoff=" << cutoff.toString("dd.MM.yyyy") + << ") — stopping scroll"; + break; + } + } + // Скроллим вниз — свайп внутри области транзакций if (scroll < maxScrolls) { if (interrupted()) { m_error = "Interrupted"; return false; } diff --git a/services/EventHandler.cpp b/services/EventHandler.cpp index c8751cc..52c46ad 100644 --- a/services/EventHandler.cpp +++ b/services/EventHandler.cpp @@ -739,10 +739,14 @@ void EventHandler::startThreadForTask(const MaterialInfo &account, const EventIn } } - // Watchdog-таймер: 5 минут — убиваем зависший поток + // Watchdog-таймер — убиваем зависший поток. + // FETCH_TRANSACTIONS листает историю транзакций и не успевает за 5 минут + // на длинных списках — даём ему 10 минут. Остальным задачам — 5 минут. + const int timeoutMin = (event.type == EventType::FetchTransactions) ? 10 : 5; + const QString timeoutMsg = QString("Script timeout (%1 min)").arg(timeoutMin); const auto timer = new QTimer(this); timer->setSingleShot(true); - connect(timer, &QTimer::timeout, this, [this, key, event]() { + connect(timer, &QTimer::timeout, this, [this, key, event, timeoutMsg]() { qWarning() << "[EventHandler] Timeout for key" << key << "- killing stuck thread."; if (QThread *thread = m_threads.value(key); thread && thread->isRunning()) { thread->requestInterruption(); @@ -766,11 +770,11 @@ void EventHandler::startThreadForTask(const MaterialInfo &account, const EventIn // } // Помечаем событие как ошибку - EventDAO::updateEvent(event.id, EventStatus::Error, "Script timeout (5 min)"); + EventDAO::updateEvent(event.id, EventStatus::Error, timeoutMsg); const QString logMsg = QString("[%1] bank=%2 material=%3: Script timeout") .arg(eventTypeToString(event.type), event.bankName, event.externalId); GeneralLogDAO::insert("CRITICAL", "EventHandler", logMsg); - sendTaskError(eventTypeToString(event.type), event.externalId, event.bankName, "Script timeout (5 min)", {}, -1, event.transactionId, event.accountId); + sendTaskError(eventTypeToString(event.type), event.externalId, event.bankName, timeoutMsg, {}, -1, event.transactionId, event.accountId); EventDAO::markSentToServer(event.id); // Убиваем банковское приложение на устройстве после таймаута @@ -791,7 +795,7 @@ void EventHandler::startThreadForTask(const MaterialInfo &account, const EventIn m_threads[key] = thr; m_timers[key] = timer; - timer->start(5 * 60 * 1000); + timer->start(timeoutMin * 60 * 1000); thr->start(); }