Skip to content

fix: add TTL cache invalidation for GPU memory info - #780

Open
add-uos wants to merge 1 commit into
linuxdeepin:masterfrom
add-uos:agent/pms-bug-bot/9e92f5e4abae
Open

add-uos wants to merge 1 commit into
linuxdeepin:masterfrom
add-uos:agent/pms-bug-bot/9e92f5e4abae

Conversation

@add-uos

@add-uos add-uos commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

fix: add TTL cache invalidation for GPU memory info

  1. Root cause: getGpuInfoForFTDTM() used a static QString that was
    never refreshed after first successful read, daemon returned stale
    GPU memory data for its entire lifetime
  2. Fix: introduce static QDateTime timestamp and 30-second TTL constant,
    re-read the underlying file when cache is empty or expired; on read
    failure the timestamp is not updated so the next call retries
  3. Impact: callers via DBus now receive data that is at most 30 seconds
    old; no interface or signature change, no impact on other callers

Log: fix stale GPU memory info in long-running daemon

Influence:

  1. Verify GPU memory info displays correctly after daemon start
  2. Verify info refreshes after 30 seconds when underlying data changes
  3. Verify graceful behavior when GPU info file is unavailable

fix: 修复GPU显存信息缓存过期问题

  1. 根因:getGpuInfoForFTDTM() 使用 static QString 永久缓存,首次成功
    读取后永不刷新,守护进程生命周期内始终返回过期数据
  2. 方案:引入 static QDateTime 时间戳和 30 秒 TTL 常量,缓存为空或已
    过期时重新读取文件;读取失败不更新时间戳,下次调用继续重试
  3. 影响:通过 DBus 调用的前端将获得最多 30 秒延迟的新鲜数据;接口
    和签名不变,对其他调用者无影响

Log: 修复守护进程长时间运行后GPU显存信息过期问题

Influence:

  1. 测试守护进程启动后 GPU 显存信息正确显示
  2. 测试底层文件变更后 30 秒内信息能自动刷新
  3. 测试 GPU 信息文件不可用时的容错行为

Summary by Sourcery

Prevent stale GPU memory information by adding time-based cache invalidation while preserving existing interfaces.

Bug Fixes:

  • Refresh GPU memory information after the cache expires so long-running daemons no longer return permanently stale data.
  • Retry GPU information reads after failures without advancing the cache timestamp.

Chores:

  • Update SPDX copyright years across affected source and test files.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Sep 21, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds 30-second TTL invalidation to the static GPU memory cache, refreshing data after expiration while retaining the previous value and retrying on read failures without changing the public interface.

Sequence diagram for GPU memory cache refresh

sequenceDiagram
    participant Caller
    participant DeviceInterface
    participant GPUInfoFile

    Caller->>DeviceInterface: getGpuInfoForFTDTM()
    DeviceInterface->>DeviceInterface: Check cache expiration
    alt Cache empty or TTL expired
        DeviceInterface->>GPUInfoFile: getGpuMemInfoForFTDTM(mapInfo)
        alt Read succeeds
            GPUInfoFile-->>DeviceInterface: GPU memory data
            DeviceInterface->>DeviceInterface: Update gpuMemInfo and lastUpdate
        else Read fails
            GPUInfoFile-->>DeviceInterface: Failure
            DeviceInterface-->>Caller: Return previous cached value
        end
    else Cache valid
        DeviceInterface-->>Caller: Return cached value
    end
    DeviceInterface-->>Caller: GPU memory info
Loading

File-Level Changes

Change Details Files
Replace the permanent GPU memory snapshot with a time-based cache that refreshes every 30 seconds.
  • Added a 30-second TTL and static last-update timestamp.
  • Reloads GPU memory data when the cache is empty or expired.
  • Updates the cached string and timestamp only after a successful read.
deepin-devicemanager-server/deepin-deviceinfo/src/loadinfo/deviceinterface.cpp
Preserve retry behavior and existing caller-facing behavior when GPU data cannot be read.
  • Leaves the timestamp unchanged on read failure so subsequent calls retry.
  • Keeps the existing return type, interface, and cached value behavior.
deepin-devicemanager-server/deepin-deviceinfo/src/loadinfo/deviceinterface.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="deepin-devicemanager-server/deepin-deviceinfo/src/loadinfo/deviceinterface.cpp" line_range="151-153" />
<code_context>
-    if (gpuMemInfo.isEmpty()) {
+    static QDateTime lastUpdate;
+
+    bool cacheExpired = !lastUpdate.isValid()
+        || lastUpdate.secsTo(QDateTime::currentDateTime()) >= kGpuCacheTtlSec;
+    if (gpuMemInfo.isEmpty() || cacheExpired) {
         QMap<QString, QString> mapInfo;
         if (getGpuMemInfoForFTDTM(mapInfo)) {
</code_context>
<issue_to_address>
**issue (bug_risk):** `lastUpdate.secsTo(QDateTime::currentDateTime())` uses wall-clock time, so a backward system-clock adjustment makes the elapsed value negative and prevents the cache from expiring until wall time catches up. The daemon then returns stale GPU data beyond the 30-second TTL.

**Triggers:** When the system clock is corrected backward or synchronized by NTP while the daemon is running.

**Suggested fix:** Use a monotonic elapsed-time source such as `QElapsedTimer` for TTL calculations.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment on lines +151 to +153
bool cacheExpired = !lastUpdate.isValid()
|| lastUpdate.secsTo(QDateTime::currentDateTime()) >= kGpuCacheTtlSec;
if (gpuMemInfo.isEmpty() || cacheExpired) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): lastUpdate.secsTo(QDateTime::currentDateTime()) uses wall-clock time, so a backward system-clock adjustment makes the elapsed value negative and prevents the cache from expiring until wall time catches up. The daemon then returns stale GPU data beyond the 30-second TTL.

Triggers: When the system clock is corrected backward or synchronized by NTP while the daemon is running.

Suggested fix: Use a monotonic elapsed-time source such as QElapsedTimer for TTL calculations.

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

AI 代码审查报告

PR: #780
分支: agent/pms-bug-bot/9e92f5e4abae → master
作者: add-uos
提交: e254193 - fix: add TTL cache invalidation for GPU memory info
修改文件: 1 个


总体评价

总分: 98/100 - 优秀

本次提交修复了 getGpuInfoForFTDTM() 函数中 GPU 显存信息永久缓存导致守护进程返回过期数据的问题。通过引入 30 秒 TTL(Time-To-Live)缓存失效机制,确保 DBus 调用方获得的数据最多延迟 30 秒。代码修改简洁、逻辑清晰,未引入安全漏洞,未改变接口签名,对其他调用者无影响。


修改文件清单

文件路径 增加行 删除行
deepin-devicemanager-server/deepin-deviceinfo/src/loadinfo/deviceinterface.cpp +9 -1

四维度评分

维度1: 语法逻辑 (25/25) ✓

语法正确,逻辑清晰

分析:

  1. #include <QDateTime> 头文件引入正确,QDateTime 类用于时间戳记录
  2. static constexpr int kGpuCacheTtlSec = 30; 编译期常量声明正确,30 秒 TTL 合理
  3. static QDateTime lastUpdate; 静态局部变量,默认构造为无效时间,首次调用时触发读取
  4. 缓存过期判断逻辑正确:!lastUpdate.isValid() || lastUpdate.secsTo(QDateTime::currentDateTime()) >= kGpuCacheTtlSec
    • 首次调用:lastUpdate 无效 → cacheExpired = true → 触发读取
    • 30 秒内调用:secsTo() 返回值 < 30 → cacheExpired = false → 跳过读取
    • 超过 30 秒:secsTo() 返回值 ≥ 30 → cacheExpired = true → 触发读取
  5. gpuMemInfo.clear() 在重新填充前清空旧数据,防止数据累积
  6. lastUpdate 仅在成功读取时更新(在 if (getGpuMemInfoForFTDTM(mapInfo)) 块内),读取失败时下次调用自动重试

边界条件分析:

  • 首次调用读取失败:gpuMemInfo 保持空,lastUpdate 保持无效 → 下次调用重试 ✓
  • 成功读取后再次失败:gpuMemInfo 保留上次有效数据,lastUpdate 不更新 → TTL 内返回旧数据,超时后重试 ✓
  • 代码无编译错误,无内存泄漏,无空指针风险

维度2: 代码质量 (23/25) ✓

代码结构清晰,可读性好

分析:

  • 命名规范 (+): kGpuCacheTtlSec(Google 风格 k 前缀常量)、lastUpdate、cacheExpired 命名清晰达意
  • 代码结构 (+): 函数逻辑分层清晰 —— 常量定义 → 状态变量 → 过期判断 → 读取更新 → 返回
  • 防御性编程 (+): gpuMemInfo.clear() 防止数据累积,lastUpdate 仅成功时更新实现自动重试
  • 无重复代码 (+): 无复制粘贴
  • 无调试残留 (+): 无 qDebug、printf 等调试代码

扣分项:

  • (-2分) 关键函数 getGpuInfoForFTDTM() 缺少注释说明 TTL 缓存策略,虽然变量命名较好,但缓存失效机制的设计意图建议添加简要注释

维度3: 代码性能 (20/20) ✓

性能良好,资源使用合理

分析:

  1. TTL 缓存优化 (+): 30 秒 TTL 避免每次 DBus 调用都读取文件,显著降低系统 I/O 开销
  2. 轻量级时间检查 (+): QDateTime::currentDateTime() 为轻量系统调用,每次调用仅执行一次
  3. 合理的数据清空策略 (+): gpuMemInfo.clear() 在成功读取后清空再填充,避免内存增长
  4. 无性能瓶颈 (+): 无频繁系统调用,无资源泄漏,算法复杂度 O(1)(缓存命中时)

维度4: 代码安全 (30/30) ✓

存在0个安全漏洞

分析:

  1. 无用户输入直接参与代码逻辑,无注入风险
  2. 无硬编码密钥或敏感信息
  3. 无缓冲区溢出风险(QString 自动管理内存)
  4. 无路径遍历风险(文件路径由 getGpuMemInfoForFTDTM() 内部管理,本次未修改)
  5. 无权限绕过风险
  6. 无不安全密码算法使用

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个


OCR 审查结果

审查工具: OpenCodeReview (OCR)
审查结果: 1 个文件已审查,0 条评论,审查耗时 5 秒
结论: No comments generated. Looks good to me.


改进建议

建议1: 添加 TTL 缓存策略注释

在 getGpuInfoForFTDTM() 函数开头添加简要注释,说明缓存机制设计意图:

QString DeviceInterface::getGpuInfoForFTDTM()
{
    // TTL cache: re-read GPU memory info every 30 seconds to avoid
    // stale data in long-running daemon. On read failure, the timestamp
    // is not updated so the next call retries automatically.
    static constexpr int kGpuCacheTtlSec = 30;
    static QString gpuMemInfo { "" };
    static QDateTime lastUpdate;
    // ...
}

审查结论

本次提交是一个高质量的 Bug 修复,解决了守护进程长时间运行后 GPU 显存信息缓存过期的问题。代码修改简洁(+9/-1),逻辑正确,边界条件处理完善,未引入安全漏洞。TTL 缓存机制设计合理,在数据新鲜度和系统性能之间取得了良好平衡。建议补充缓存策略注释以提升可维护性。

评分明细:

维度 得分 满分 状态
语法逻辑 25 25 ✓
代码质量 23 25 ✓
代码性能 20 20 ✓
代码安全 30 30 ✓
总分 98 100 优秀

@add-uos
add-uos force-pushed the agent/pms-bug-bot/9e92f5e4abae branch from e254193 to 7636578 Compare September 22, 2026 02:31
@deepin-bot

deepin-bot Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

TAG Bot

New tag: 6.0.74
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #839

1. Root cause: getGpuInfoForFTDTM() used a static QString that was
   never refreshed after first successful read, daemon returned stale
   GPU memory data for its entire lifetime
2. Fix: introduce static QDateTime timestamp and 30-second TTL constant,
   re-read the underlying file when cache is empty or expired; on read
   failure the timestamp is not updated so the next call retries
3. Impact: callers via DBus now receive data that is at most 30 seconds
   old; no interface or signature change, no impact on other callers

Log: fix stale GPU memory info in long-running daemon

Influence:
1. Verify GPU memory info displays correctly after daemon start
2. Verify info refreshes after 30 seconds when underlying data changes
3. Verify graceful behavior when GPU info file is unavailable

fix: 修复GPU显存信息缓存过期问题

1. 根因:getGpuInfoForFTDTM() 使用 static QString 永久缓存,首次成功
   读取后永不刷新,守护进程生命周期内始终返回过期数据
2. 方案:引入 static QDateTime 时间戳和 30 秒 TTL 常量,缓存为空或已
   过期时重新读取文件;读取失败不更新时间戳,下次调用继续重试
3. 影响:通过 DBus 调用的前端将获得最多 30 秒延迟的新鲜数据;接口
   和签名不变,对其他调用者无影响

Log: 修复守护进程长时间运行后GPU显存信息过期问题

Influence:
1. 测试守护进程启动后 GPU 显存信息正确显示
2. 测试底层文件变更后 30 秒内信息能自动刷新
3. 测试 GPU 信息文件不可用时的容错行为
@add-uos
add-uos force-pushed the agent/pms-bug-bot/9e92f5e4abae branch from 7636578 to 1826a2c Compare October 27, 2026 04:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants