fix: resolve high CPU usage and account loading failures#320
fix: resolve high CPU usage and account loading failures#320wyu71 merged 1 commit intolinuxdeepin:masterfrom
Conversation
Reviewer's GuideThis PR fixes high CPU usage from an infinite DBus-driven year-view refresh loop and addresses intermittent account info loading failures by switching the year view to use cached lunar data with anti-reentry protection, correcting lunar range filters, optimizing timer-driven view updates, and adding synchronous fallbacks for failed DBus account/general-settings calls. Sequence diagram for year view lunar data loading with caching and anti reentrysequenceDiagram
actor User
participant MainWindow as Calendarmainwindow
participant YearWin as CYearWindow
participant LunarMgr as LunarManager
participant DBus as DBusLunarService
User ->> MainWindow: Open year view
MainWindow ->> YearWin: show()
User ->> YearWin: Enable lunar display
YearWin ->> LunarMgr: ensureLunarDataLoaded(yearStart, yearEnd)
alt Range already fully cached
LunarMgr --> YearWin: Return (no DBus calls)
YearWin ->> LunarMgr: getHuangLiDayMap(yearStart, yearEnd)
YearWin ->> LunarMgr: getFestivalInfoDateMap(yearStart, yearEnd)
YearWin --> User: Render year view with cached lunar data
else Range not fully cached and not pending
LunarMgr ->> LunarMgr: Insert (yearStart, yearEnd) into m_pendingQueries
LunarMgr ->> DBus: Async queryLunarInfo(yearStart, yearEnd)
LunarMgr ->> DBus: Async queryFestivalInfo(yearStart, yearEnd)
DBus -->> LunarMgr: lunar data result
LunarMgr ->> LunarMgr: Merge result into m_lunarInfoMap
LunarMgr ->> LunarMgr: Remove (yearStart, yearEnd) from m_pendingQueries
LunarMgr ->> YearWin: emit lunarInfoReady()
DBus -->> LunarMgr: festival data result
LunarMgr ->> LunarMgr: Update m_festivalDateMap
LunarMgr ->> LunarMgr: Remove (yearStart, yearEnd) from m_pendingQueries (idempotent)
LunarMgr ->> YearWin: emit festivalInfoReady()
YearWin ->> LunarMgr: getHuangLiDayMap(yearStart, yearEnd)
YearWin ->> LunarMgr: getFestivalInfoDateMap(yearStart, yearEnd)
YearWin --> User: Render year view with newly cached lunar data
end
Note over LunarMgr: If ensureLunarDataLoaded is called again for the same range
LunarMgr ->> LunarMgr: Check m_pendingQueries
LunarMgr --> YearWin: Return immediately to prevent reentrant DBus queries
Sequence diagram for DBus account list loading with synchronous retrysequenceDiagram
actor User
participant UI as AccountUI
participant Req as DbusAccountManagerRequest
participant DBus as DBusAccountService
User ->> UI: Open accounts panel
UI ->> Req: Async getAccountList()
Req ->> DBus: callWithArgumentList(Async, getAccountList, args)
DBus -->> Req: Async reply (error)
Req ->> Req: slotCallFinished(call)
Req ->> Req: Detect isError() and getmember() == getAccountList
Req ->> Req: Log warning
Req ->> DBus: callWithArgumentList(Block, getAccountList, emptyArgs)
DBus -->> Req: Sync reply(accountJson)
Req ->> Req: DAccount::fromJsonListString(accountList, accountJson)
Req -->> UI: signalGetAccountListFinish(accountList)
UI --> User: Show account list
opt General settings load
UI ->> Req: Async getCalendarGeneralSettings()
Req ->> DBus: callWithArgumentList(Async, getCalendarGeneralSettings, args)
DBus -->> Req: Async reply (error)
Req ->> Req: slotCallFinished(call)
Req ->> Req: Detect isError() and getmember() == getCalendarGeneralSettings
Req ->> DBus: callWithArgumentList(Block, getCalendarGeneralSettings, emptyArgs)
DBus -->> Req: Sync reply(settingsJson)
Req ->> Req: DCalendarGeneralSettings::fromJsonString(settingsPtr, settingsJson)
Req -->> UI: signalGetGeneralSettingsFinish(settingsPtr)
end
Class diagram for updated lunar data loading and DBus retry logicclassDiagram
class LunarManager {
+QMap~QDate, CaHuangLiDayInfo~ m_lunarInfoMap
+QMap~QDate, int~ m_festivalDateMap
+QList~QPair~QDate, QDate~~ m_queriedRanges
+QSet~QPair~QDate, QDate~~ m_pendingQueries
+void queryLunarInfo(QDate startDate, QDate stopDate)
+void queryFestivalInfo(QDate startDate, QDate stopDate)
+QMap~QDate, CaHuangLiDayInfo~ getHuangLiDayMap(QDate startDate, QDate stopDate)
+QMap~QDate, int~ getFestivalInfoDateMap(QDate startDate, QDate stopDate)
+void ensureLunarDataLoaded(QDate startDate, QDate endDate)
+static LunarManager* getInstace()
}
class CYearWindow {
+void updateShowLunar()
+QDate getSelectDate()
}
class Calendarmainwindow {
+void slotCurrentDateUpdate()
-QStackedWidget* m_stackWidget
-CScheduleBaseWidget* m_DayWindow
-CScheduleBaseWidget* m_monthWindow
-CYearWindow* m_yearwindow
}
class CScheduleBaseWidget {
+void updateData()
}
class CDynamicIcon {
+static CDynamicIcon* getInstance()
+QDate getDate()
+void setDate(QDate date)
+void setIcon()
}
class DbusAccountManagerRequest {
+void slotCallFinished(CDBusPendingCallWatcher* call)
+QDBusReply~QString~ callWithArgumentList(QDBus::CallMode mode, QString method, QList~QVariant~ args)
+void signalGetAccountListFinish(DAccount::List accountList)
+void signalGetGeneralSettingsFinish(DCalendarGeneralSettings::Ptr settings)
}
class CDBusPendingCallWatcher {
+bool isError()
+QDBusMessage reply()
+QDBusError error()
+QString getmember()
}
class DAccount {
<<static>> bool fromJsonListString(DAccount::List accountList, QString json)
+typedef QList~DAccount~ List
}
class DCalendarGeneralSettings {
+typedef QSharedPointer~DCalendarGeneralSettings~ Ptr
<<static>> bool fromJsonString(DCalendarGeneralSettings::Ptr settings, QString json)
}
CYearWindow --> LunarManager : uses gLunarManager
Calendarmainwindow o--> CYearWindow : owns
Calendarmainwindow o--> CScheduleBaseWidget : owns via m_stackWidget
Calendarmainwindow --> CDynamicIcon : uses
DbusAccountManagerRequest --> CDBusPendingCallWatcher : handles
DbusAccountManagerRequest --> DAccount : parses account list
DbusAccountManagerRequest --> DCalendarGeneralSettings : parses settings
LunarManager --> QDBusInterface : uses for DBus calls
LunarManager --> QFutureWatcher : uses for async queries
LunarManager --> QMap
LunarManager --> QSet
LunarManager --> QList
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The synchronous
callWithArgumentList(QDBus::Block, ...)retries insideslotCallFinishedrisk blocking the main thread/event loop on DBus failure; consider moving the blocking retry to a worker thread or using a bounded, non-blocking fallback strategy to avoid UI stalls. - Using
QSet<QPair<QDate, QDate>> m_pendingQueriesrelies on a suitableqHashforQPair<QDate,QDate>; verify that your Qt version provides this or add an explicitqHashoverload, otherwise membership checks may not compile or behave as expected.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The synchronous `callWithArgumentList(QDBus::Block, ...)` retries inside `slotCallFinished` risk blocking the main thread/event loop on DBus failure; consider moving the blocking retry to a worker thread or using a bounded, non-blocking fallback strategy to avoid UI stalls.
- Using `QSet<QPair<QDate, QDate>> m_pendingQueries` relies on a suitable `qHash` for `QPair<QDate,QDate>`; verify that your Qt version provides this or add an explicit `qHash` overload, otherwise membership checks may not compile or behave as expected.
## Individual Comments
### Comment 1
<location path="src/calendar-client/src/dbus/dbusaccountmanagerrequest.cpp" line_range="199-208" />
<code_context>
+ if (call->getmember() == "getAccountList") {
</code_context>
<issue_to_address>
**issue (bug_risk):** Return status `ret` is always set to error even if the synchronous retry succeeds.
You’re unconditionally setting `ret = 1` in the error branch after the synchronous retry. As a result, callers of `slotCallFinished` will still see an error even when the retry successfully decodes the response and emits the finish signals. Please either update `ret` based on the retry result or bypass the outer error handling when the retry succeeds.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
Note
详情{
"src/calendar-client/src/widget/calendarmainwindow.cpp": [
{
"line": " url = \"https://www.deepin.org/zh/agreement/privacy/\";",
"line_number": 1168,
"rule": "S35",
"reason": "Url link | 20e2eab189"
},
{
"line": " url = \"https://www.uniontech.com/agreement/privacy-cn\";",
"line_number": 1170,
"rule": "S35",
"reason": "Url link | 4850a00dd7"
},
{
"line": " url = \"https://www.deepin.org/en/agreement/privacy/\";",
"line_number": 1174,
"rule": "S35",
"reason": "Url link | 38d42f63bf"
},
{
"line": " url = \"https://www.uniontech.com/agreement/privacy-en\";",
"line_number": 1176,
"rule": "S35",
"reason": "Url link | f82409d3b5"
}
]
} |
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持续满载,修复账户信息偶尔永久不显示, 优化定时器驱动的视图重绘减少不必要的开销。
|
Note
详情{
"src/calendar-client/src/widget/calendarmainwindow.cpp": [
{
"line": " url = \"https://www.deepin.org/zh/agreement/privacy/\";",
"line_number": 1168,
"rule": "S35",
"reason": "Url link | 20e2eab189"
},
{
"line": " url = \"https://www.uniontech.com/agreement/privacy-cn\";",
"line_number": 1170,
"rule": "S35",
"reason": "Url link | 4850a00dd7"
},
{
"line": " url = \"https://www.deepin.org/en/agreement/privacy/\";",
"line_number": 1174,
"rule": "S35",
"reason": "Url link | 38d42f63bf"
},
{
"line": " url = \"https://www.uniontech.com/agreement/privacy-en\";",
"line_number": 1176,
"rule": "S35",
"reason": "Url link | f82409d3b5"
}
]
} |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: lzwind, wyu71 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
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持续满载,修复账户信息偶尔永久不显示,
优化定时器驱动的视图重绘减少不必要的开销。
Summary by Sourcery
Resolve high CPU usage and intermittent account data loading failures by improving lunar data caching, preventing redundant DBus queries, and adding synchronous fallbacks for critical DBus calls.
Bug Fixes:
Enhancements: