Skip to content

Commit 2b15a79

Browse files
committed
fix: resolve high CPU usage and account loading failures
Fix infinite DBus loop in year view by using cached lunar data loading instead of direct queries. Fix range filter bug (|| to &&) in lunar manager. Add anti-reentry protection for in-flight queries. Optimize timer-driven repaints to only update visible view. Retry failed DBus calls synchronously to prevent permanent account info loss. 修复年视图无限DBus循环导致CPU满占用,改用缓存的农历数据加载。 修复农历管理器日期范围过滤条件错误(||改&&),增加查询中防重入 保护。优化定时器重绘只更新当前可见视图。DBus异步调用失败时 同步重试,防止账户信息永久不显示。 Log: 修复CPU高占用和账户信息加载失败问题 PMS: BUG-355799 Influence: 修复年视图无限信号循环导致CPU持续满载,修复账户信息偶尔永久不显示, 优化定时器驱动的视图重绘减少不必要的开销。
1 parent af2ce44 commit 2b15a79

5 files changed

Lines changed: 65 additions & 18 deletions

File tree

src/calendar-client/src/dataManage/lunarmanager.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,13 @@ void LunarManager::queryLunarInfo(const QDate &startDate, const QDate &stopDate)
157157
delete dbus;
158158
return lunarInfoMap;
159159
});
160-
connect(w, &QFutureWatcher<QMap<QDate, CaHuangLiDayInfo>>::finished, this, [this, w]() {
161-
m_lunarInfoMap = w->result();
162-
qCDebug(ClientLogger) << "Lunar info query completed with" << m_lunarInfoMap.size() << "days";
160+
connect(w, &QFutureWatcher<QMap<QDate, CaHuangLiDayInfo>>::finished, this, [this, w, startDate, stopDate]() {
161+
auto result = w->result();
162+
for (auto it = result.constBegin(); it != result.constEnd(); ++it) {
163+
m_lunarInfoMap[it.key()] = it.value();
164+
}
165+
m_pendingQueries.remove(qMakePair(startDate, stopDate));
166+
qCDebug(ClientLogger) << "Lunar info query completed, total cached:" << m_lunarInfoMap.size() << "days";
163167
w->deleteLater();
164168
emit lunarInfoReady();
165169
});
@@ -191,14 +195,14 @@ void LunarManager::queryFestivalInfo(const QDate &startDate, const QDate &stopDa
191195
delete dbus;
192196
return festivallist;
193197
});
194-
connect(w, &QFutureWatcher<QVector<FestivalInfo>>::finished, this, [this, w]() {
198+
connect(w, &QFutureWatcher<QVector<FestivalInfo>>::finished, this, [this, w, startDate, stopDate]() {
195199
auto festivallist = w->result();
196-
m_festivalDateMap.clear();
197200
for (const FestivalInfo &info : festivallist) {
198201
for (const HolidayInfo &h : info.listHoliday) {
199202
m_festivalDateMap[h.date] = h.status;
200203
}
201204
}
205+
m_pendingQueries.remove(qMakePair(startDate, stopDate));
202206
qCDebug(ClientLogger) << "Festival date map updated with" << m_festivalDateMap.size() << "days";
203207
w->deleteLater();
204208
emit festivalInfoReady();
@@ -274,7 +278,7 @@ QMap<QDate, CaHuangLiDayInfo> LunarManager::getHuangLiDayMap(const QDate &startD
274278
QMap<QDate, CaHuangLiDayInfo> lunarInfoMap;
275279
auto iterator = m_lunarInfoMap.begin();
276280
while(iterator != m_lunarInfoMap.end()) {
277-
if (iterator.key() >= startDate || iterator.key() <= stopDate) {
281+
if (iterator.key() >= startDate && iterator.key() <= stopDate) {
278282
iterator.value();
279283
lunarInfoMap[iterator.key()] = iterator.value();
280284
}
@@ -297,7 +301,7 @@ QMap<QDate, int> LunarManager::getFestivalInfoDateMap(const QDate &startDate, co
297301
QMap<QDate, int> festivalDateMap;
298302
auto iterator = m_festivalDateMap.begin();
299303
while(iterator != m_festivalDateMap.end()) {
300-
if (iterator.key() >= startDate || iterator.key() <= stopDate) {
304+
if (iterator.key() >= startDate && iterator.key() <= stopDate) {
301305
iterator.value();
302306
festivalDateMap[iterator.key()] = iterator.value();
303307
}
@@ -321,6 +325,12 @@ void LunarManager::ensureLunarDataLoaded(const QDate &startDate, const QDate &en
321325
return;
322326
}
323327

328+
// Prevent re-entrant queries for the same range while DBus call is in flight
329+
auto key = qMakePair(startDate, endDate);
330+
if (m_pendingQueries.contains(key)) {
331+
return;
332+
}
333+
324334
// Check if this range (or a superset) has already been queried
325335
for (const auto &range : m_queriedRanges) {
326336
if (startDate >= range.first && endDate <= range.second) {
@@ -338,6 +348,7 @@ void LunarManager::ensureLunarDataLoaded(const QDate &startDate, const QDate &en
338348
if (cachedDays < expectedDays) {
339349
qCDebug(ClientLogger) << "Querying lunar data for range" << startDate.toString() << "to" << endDate.toString()
340350
<< "expected:" << expectedDays << "cached:" << cachedDays;
351+
m_pendingQueries.insert(key);
341352
queryLunarInfo(startDate, endDate);
342353
queryFestivalInfo(startDate, endDate);
343354
}

src/calendar-client/src/dataManage/lunarmanager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public slots:
6363
QMap<QDate, CaHuangLiDayInfo> m_lunarInfoMap; //缓存的农历数据
6464
QMap<QDate, int> m_festivalDateMap; //缓存的节假日数据
6565
QList<QPair<QDate, QDate>> m_queriedRanges; //已查询的日期范围缓存
66+
QSet<QPair<QDate, QDate>> m_pendingQueries; //正在查询中的范围,防止重入
6667

6768
};
6869
#define gLunarManager LunarManager::getInstace()

src/calendar-client/src/dbus/dbusaccountmanagerrequest.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "commondef.h"
77
#include "dcalendargeneralsettings.h"
88
#include <QDBusInterface>
9+
#include <QDBusReply>
910
#include <QDebug>
1011

1112
DbusAccountManagerRequest::DbusAccountManagerRequest(QObject *parent)
@@ -192,9 +193,43 @@ void DbusAccountManagerRequest::slotCallFinished(CDBusPendingCallWatcher *call)
192193

193194
//错误处理
194195
if (call->isError()) {
195-
qCWarning(ClientLogger) << "DBus call error - Method:" << call->reply().member()
196+
qCWarning(ClientLogger) << "DBus call error - Method:" << call->reply().member()
196197
<< "Error:" << call->error().message();
197-
ret = 1;
198+
// Retry critical calls synchronously on failure
199+
if (call->getmember() == "getAccountList") {
200+
qCInfo(ClientLogger) << "Retrying getAccountList synchronously";
201+
QDBusReply<QString> reply = callWithArgumentList(QDBus::Block, "getAccountList", QList<QVariant>());
202+
if (reply.isValid()) {
203+
DAccount::List accountList;
204+
if (DAccount::fromJsonListString(accountList, reply.value())) {
205+
emit signalGetAccountListFinish(accountList);
206+
canCall = false;
207+
}
208+
}
209+
if (canCall) ret = 1;
210+
} else if (call->getmember() == "getCalendarGeneralSettings") {
211+
qCInfo(ClientLogger) << "Retrying getCalendarGeneralSettings synchronously";
212+
QDBusReply<QString> reply = callWithArgumentList(QDBus::Block, "getCalendarGeneralSettings", QList<QVariant>());
213+
if (reply.isValid()) {
214+
DCalendarGeneralSettings::Ptr ptr;
215+
ptr.reset(new DCalendarGeneralSettings());
216+
if (DCalendarGeneralSettings::fromJsonString(ptr, reply.value())) {
217+
emit signalGetGeneralSettingsFinish(ptr);
218+
canCall = false;
219+
}
220+
}
221+
if (canCall) ret = 1;
222+
} else if (call->getmember() == "isSupportUid") {
223+
qCInfo(ClientLogger) << "Retrying isSupportUid synchronously";
224+
QDBusReply<bool> reply = callWithArgumentList(QDBus::Block, "isSupportUid", QList<QVariant>());
225+
if (reply.isValid()) {
226+
emit signalGetIsSupportUidFinish(reply.value());
227+
canCall = false;
228+
}
229+
if (canCall) ret = 1;
230+
} else {
231+
ret = 1;
232+
}
198233
} else if (call->getmember() == "getAccountList") {
199234
qCDebug(ClientLogger) << "Processing getAccountList response";
200235
QDBusPendingReply<QString> reply = *call;

src/calendar-client/src/widget/calendarmainwindow.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,22 +204,23 @@ void Calendarmainwindow::slotCurrentDateUpdate()
204204
// qCDebug(ClientLogger) << "Calendarmainwindow::slotCurrentDateUpdate";
205205
//获取当前时间
206206
const QDateTime _currentDate = QDateTime::currentDateTime();
207-
//设置当前时间
208-
if (m_DayWindow) m_DayWindow->setCurrentDateTime(_currentDate);
207+
//只对日视图更新当前时间(用于时间线绘制),仅当日视图可见时
208+
if (m_DayWindow && m_stackWidget->currentIndex() == DDECalendar::CalendarDayWindow)
209+
m_DayWindow->setCurrentDateTime(_currentDate);
209210
//如果当前日期与动态图标日期不一样则重新生成动态图标
210211
if (_currentDate.date() != CDynamicIcon::getInstance()->getDate()) {
211212
qCDebug(ClientLogger) << "Updating dynamic icon date" << "new date:" << QDate::currentDate();
212213
CDynamicIcon::getInstance()->setDate(QDate::currentDate());
213214
CDynamicIcon::getInstance()->setIcon();
214-
//更新视图数据显示
215-
for (int i = 0; i < m_stackWidget->count(); ++i) {
216-
CScheduleBaseWidget *widget = qobject_cast<CScheduleBaseWidget *>(m_stackWidget->widget(i));
217-
if (widget) widget->updateData();
218-
}
215+
//更新当前可见视图数据显示
216+
CScheduleBaseWidget *currentWidget = qobject_cast<CScheduleBaseWidget *>(m_stackWidget->currentWidget());
217+
if (currentWidget) currentWidget->updateData();
219218
//设置年视图年数据时间显示
220219
if (m_yearwindow) m_yearwindow->setYearData();
221220
//更新月视图当前周横线绘制
222221
if (m_monthWindow) m_monthWindow->setCurrentDateTime(_currentDate);
222+
//日期变化时也要更新日视图时间
223+
if (m_DayWindow) m_DayWindow->setCurrentDateTime(_currentDate);
223224
}
224225
}
225226

src/calendar-client/src/widget/yearWidget/yearwindow.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,8 +524,7 @@ void CYearWindow::updateShowLunar()
524524
if (getShowLunar()) {
525525
QDate yearStart(getSelectDate().year(), 1, 1);
526526
QDate yearEnd(getSelectDate().year(), 12, 31);
527-
gLunarManager->queryLunarInfo(yearStart, yearEnd);
528-
gLunarManager->queryFestivalInfo(yearStart, yearEnd);
527+
gLunarManager->ensureLunarDataLoaded(yearStart, yearEnd);
529528
}
530529

531530
//获取农历信息

0 commit comments

Comments
 (0)