Skip to content

feat: manage QML cache versioning proactively#2898

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
18202781743:cache
Dec 24, 2025
Merged

feat: manage QML cache versioning proactively#2898
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
18202781743:cache

Conversation

@18202781743

@18202781743 18202781743 commented Dec 24, 2025

Copy link
Copy Markdown
Contributor

Added QML cache management to handle version changes and prevent stale
cache issues. The changes include:

  1. Added refreshQmlCache() function to manage QML disk cache based on
    application version
  2. Moved application version setting earlier in main() to enable cache
    management
  3. The cache management function checks for existing cache directory and
    removes it if version mismatch is detected
  4. Creates new cache directory with current version to ensure fresh
    QML compilation
  5. Added QDir include for directory operations

This change is necessary because QML cache can become stale when
application version changes, leading to potential runtime issues. By
proactively managing the cache directory based on version, we ensure
that QML components are recompiled when needed.

Log: Improved QML cache management to handle version changes
automatically

Influence:

  1. Test application startup with different version strings
  2. Verify QML cache directory creation and cleanup
  3. Test with QML_DISK_CACHE_PATH environment variable set
  4. Verify QML component loading after version change
  5. Test cache persistence across application restarts
  6. Monitor for any QML compilation performance changes

feat: 主动管理 QML 缓存版本控制

添加了 QML 缓存管理功能以处理版本变更并防止缓存过期问题。变更包括:

  1. 添加 refreshQmlCache() 函数来根据应用版本管理 QML 磁盘缓存
  2. 将应用版本设置移到 main() 函数更早的位置以启用缓存管理
  3. 缓存管理函数检查现有缓存目录,如果检测到版本不匹配则删除旧缓存
  4. 创建带有当前版本的新缓存目录以确保 QML 重新编译
  5. 添加 QDir 包含以支持目录操作

此变更是必要的,因为当应用版本变更时,QML 缓存可能变得过时,导致潜在的
运行时问题。通过基于版本主动管理缓存目录,我们确保在需要时重新编译 QML
组件。

Log: 改进 QML 缓存管理以自动处理版本变更

Influence:

  1. 使用不同版本字符串测试应用启动
  2. 验证 QML 缓存目录的创建和清理
  3. 测试设置 QML_DISK_CACHE_PATH 环境变量的情况
  4. 验证版本变更后的 QML 组件加载
  5. 测试跨应用重启的缓存持久性
  6. 监控 QML 编译性能变化

Summary by Sourcery

Add proactive QML disk cache management based on the application version during startup to avoid using stale QML cache after upgrades.

New Features:

  • Introduce a refreshQmlCache helper that manages the QML disk cache directory according to the current application version on startup.

Enhancements:

  • Set the application version earlier in main() so it can be used for QML cache management.
  • Support custom QML cache locations via the QML_DISK_CACHE_PATH environment variable when managing cache directories.

@sourcery-ai

sourcery-ai Bot commented Dec 24, 2025

Copy link
Copy Markdown

Reviewer's Guide

Implements proactive QML disk cache versioning by introducing a refreshQmlCache helper, wiring it into main() early in application startup, and adjusting application version initialization so that stale QML cache directories are removed when the app version changes.

Sequence diagram for application startup with QML cache refresh

sequenceDiagram
    actor User
    participant App as Application
    participant Env as Environment
    participant FS as FileSystem

    User->>App: start(argc, argv)
    App->>App: setOrganizationName
    App->>App: setApplicationName

    App->>App: determine applicationVersion
    App->>App: setApplicationVersion(version)

    App->>Env: qgetenv(QML_DISK_CACHE_PATH)
    Env-->>App: envCachePath

    App->>FS: refreshQmlCache(version)
    FS->>FS: resolve cache directory
    FS->>FS: check directory exists
    alt cache directory exists
        FS->>FS: check subdirectory version exists
        alt version directory exists
            FS-->>App: keep existing cache
        else version directory does not exist
            FS->>FS: removeRecursively(cacheDirectory)
            FS-->>App: old cache removed
            FS->>FS: mkpath(version)
            FS-->>App: new version cache created
        end
    else cache directory does not exist
        FS->>FS: mkpath(version)
        FS-->>App: version cache created
    end

    App->>App: continue startup and QML loading
    App-->>User: control center ready
Loading

File-Level Changes

Change Details Files
Add refreshQmlCache helper to manage QML disk cache based on application version and optional QML_DISK_CACHE_PATH override.
  • Introduce static refreshQmlCache(const QString &version) that no-ops on empty version strings.
  • Determine cache directory from QML_DISK_CACHE_PATH environment variable when set, otherwise default to QStandardPaths::CacheLocation + /qmlcache/.
  • Use QDir to check for existing cache directory, remove it recursively when the version subdirectory does not exist, and log the result via qWarning.
  • Ensure a fresh cache directory by creating a subdirectory named after the current version with QDir::mkpath.
src/dde-control-center/main.cpp
Move application version initialization earlier in main() and invoke QML cache refresh immediately after version setup.
  • Set organization and application name as before, then initialize application version using CVERSION macro when available or fallback "6.0" string.
  • Call refreshQmlCache(app->applicationVersion()) immediately after setting the application version to ensure cache is managed before further startup work.
  • Remove the previous application version initialization block that occurred later in main() to avoid duplication and ensure a single source of truth.
src/dde-control-center/main.cpp
Enable directory operations needed for cache management.
  • Include at the top of main.cpp to support filesystem operations in refreshQmlCache.
src/dde-control-center/main.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, and left some high level feedback:

  • Using app->applicationVersion() directly as a directory name may lead to invalid or problematic paths on some platforms (e.g. characters like /, :); consider normalizing/sanitizing the version string before using it in refreshQmlCache.
  • The cache invalidation path logs with qWarning() on every version change, which is expected rather than exceptional behavior; consider downgrading this to qInfo() or adding more context so that real issues stand out in logs.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Using `app->applicationVersion()` directly as a directory name may lead to invalid or problematic paths on some platforms (e.g. characters like `/`, `:`); consider normalizing/sanitizing the version string before using it in `refreshQmlCache`.
- The cache invalidation path logs with `qWarning()` on every version change, which is expected rather than exceptional behavior; consider downgrading this to `qInfo()` or adding more context so that real issues stand out in logs.

## Individual Comments

### Comment 1
<location> `src/dde-control-center/main.cpp:55-64` </location>
<code_context>
     return path;
 }

+static void refreshQmlCache(const QString &version)
+{
+    if (version.isEmpty())
+        return;
+    static const QByteArray envCachePath = qgetenv("QML_DISK_CACHE_PATH");
+
+    QString directory = envCachePath.isEmpty()
+            ? QStandardPaths::writableLocation(QStandardPaths::CacheLocation)
+                    + QLatin1String("/qmlcache/")
+            : QString::fromLocal8Bit(envCachePath) + QLatin1String("/");
+
+    QDir dir(directory);
+    if (dir.exists()) {
+        if (dir.exists(version))
+            return;
+        const auto ret = dir.removeRecursively();
+        qWarning() << "Remove old QML cache:" << directory << "result:" << ret;
+    }
</code_context>

<issue_to_address>
**issue (bug_risk):** Removing the entire cache directory on version change may be overly aggressive and risky.

The logic deletes the entire cache root (e.g. `${CacheLocation}/qmlcache/` or `QML_DISK_CACHE_PATH`) whenever the specific `version` subdirectory is missing. If that path is shared between QML versions or apps, this can erase unrelated caches. Please either scope the cache directory more narrowly (e.g. per app) or delete only outdated version subdirectories instead of calling `removeRecursively()` on the root path.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, BLumia, caixr23

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

1 similar comment
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, BLumia, caixr23

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

Added QML cache management to handle version changes and prevent stale
cache issues. The changes include:
1. Added refreshQmlCache() function to manage QML disk cache based on
application version
2. Moved application version setting earlier in main() to enable cache
management
3. The cache management function checks for existing cache directory and
removes it if version mismatch is detected
4. Creates new cache directory with current version to ensure fresh
QML compilation
5. Added QDir include for directory operations

This change is necessary because QML cache can become stale when
application version changes, leading to potential runtime issues. By
proactively managing the cache directory based on version, we ensure
that QML components are recompiled when needed.

Log: Improved QML cache management to handle version changes
automatically

Influence:
1. Test application startup with different version strings
2. Verify QML cache directory creation and cleanup
3. Test with QML_DISK_CACHE_PATH environment variable set
4. Verify QML component loading after version change
5. Test cache persistence across application restarts
6. Monitor for any QML compilation performance changes

feat: 主动管理 QML 缓存版本控制

添加了 QML 缓存管理功能以处理版本变更并防止缓存过期问题。变更包括:
1. 添加 refreshQmlCache() 函数来根据应用版本管理 QML 磁盘缓存
2. 将应用版本设置移到 main() 函数更早的位置以启用缓存管理
3. 缓存管理函数检查现有缓存目录,如果检测到版本不匹配则删除旧缓存
4. 创建带有当前版本的新缓存目录以确保 QML 重新编译
5. 添加 QDir 包含以支持目录操作

此变更是必要的,因为当应用版本变更时,QML 缓存可能变得过时,导致潜在的
运行时问题。通过基于版本主动管理缓存目录,我们确保在需要时重新编译 QML
组件。

Log: 改进 QML 缓存管理以自动处理版本变更

Influence:
1. 使用不同版本字符串测试应用启动
2. 验证 QML 缓存目录的创建和清理
3. 测试设置 QML_DISK_CACHE_PATH 环境变量的情况
4. 验证版本变更后的 QML 组件加载
5. 测试跨应用重启的缓存持久性
6. 监控 QML 编译性能变化
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

我来对这个diff进行代码审查:

  1. 语法逻辑:
  • 代码语法正确,没有明显语法错误
  • refreshQmlCache函数逻辑清晰,先检查版本是否为空,然后获取缓存路径,最后清理旧缓存并创建新缓存目录
  1. 代码质量:
  • 函数refreshQmlCache职责单一,符合单一职责原则
  • 使用了QDir进行目录操作,符合Qt的编程风格
  • 添加了必要的错误处理(如检查版本是否为空)
  • 有适当的调试输出,方便问题排查
  1. 代码性能:
  • removeRecursively()可能会是一个耗时操作,特别是当缓存目录很大时
  • 建议在removeRecursively()之前先检查目录是否真的需要清理
  • 可以考虑异步执行清理操作,避免阻塞主线程
  1. 代码安全:
  • 使用了QStandardPaths获取标准路径,相对安全
  • 对环境变量QML_DISK_CACHE_PATH的处理使用了qgetenv,这是安全的
  • 建议在创建目录前检查权限
  • 建议对版本字符串进行合法性检查,防止路径遍历攻击

改进建议:

  1. 添加版本字符串的合法性检查:
static bool isValidVersion(const QString &version) {
    // 检查版本字符串是否只包含数字和点
    QRegularExpression re("^[0-9.]+$");
    return re.match(version).hasMatch();
}

static void refreshQmlCache(const QString &version) {
    if (version.isEmpty() || !isValidVersion(version))
        return;
    // 其余代码保持不变
}
  1. 添加权限检查:
QDir dir(directory);
if (dir.exists()) {
    // 添加权限检查
    if (!dir.isReadable()) {
        qWarning() << "Cannot read cache directory:" << directory;
        return;
    }
    // 其余代码保持不变
}
  1. 考虑异步执行清理操作:
// 可以使用QtConcurrent::run来异步执行清理操作
QtConcurrent::run([directory, version] {
    QDir dir(directory);
    if (dir.exists()) {
        const auto ret = dir.removeRecursively();
        qDebug() << "Remove old QML cache:" << directory << "result:" << ret;
    }
    dir.mkpath(version);
});
  1. 添加更详细的错误处理:
if (!dir.mkpath(version)) {
    qWarning() << "Failed to create cache directory:" << directory + version;
}

这些改进可以提高代码的健壮性、安全性和性能。特别是版本字符串的检查和异步执行清理操作,这些改进对于生产环境来说是很重要的。

@18202781743

Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot

deepin-bot Bot commented Dec 24, 2025

Copy link
Copy Markdown

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit d2ebd8f into linuxdeepin:master Dec 24, 2025
16 of 18 checks passed
@18202781743

Copy link
Copy Markdown
Contributor Author

对应bug单子 https://pms.uniontech.com/bug-view-344855.html

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.

4 participants