Skip to content

Conversation

@18202781743
Copy link
Contributor

@18202781743 18202781743 commented Jul 1, 2025

  1. Added new reload D-Bus interface for automatic config file change
    detection
  2. Implemented multi-level file change detection (time + signature
    comparison)
  3. Added system time reset detection to handle time jumps/reboots
  4. Replaced trigger handler script with simpler reload handler
  5. Added file signature caching for efficient change detection
  6. Improved config file validation with directory monitoring
  7. Updated documentation for new reload interface

Key technical details:

  • Uses file metadata change time (ctime) as primary detection
  • Falls back to file size comparison when time is unreliable
  • Maintains startup and last reload timestamps for reference
  • Handles system time resets by clearing cached signatures
  • Automatically scans all standard config directories
  • More efficient than per-file update calls

feat: 实现智能检测的配置重载功能

  1. 新增自动检测配置文件变化的 reload D-Bus 接口
  2. 实现多层次文件变化检测(时间戳+文件签名对比)
  3. 添加系统时间重置检测处理时间跳跃/重启
  4. 用更简单的重载处理器替换触发器脚本
  5. 添加文件签名缓存提高变化检测效率
  6. 改进带目录监控的配置文件验证
  7. 更新文档说明新的重载接口

关键技术细节:

  • 使用文件元数据变更时间(ctime)作为主要检测依据
  • 时间不可靠时回退到文件大小比较
  • 维护启动时间和最后重载时间作为参考
  • 通过清除缓存签名处理系统时间重置
  • 自动扫描所有标准配置目录
  • 比逐个文件调用update更高效

Summary by Sourcery

Introduce a new reload D-Bus interface to automatically detect and apply configuration file changes across all standard directories using multi-level detection (ctime and file signature), handle system time resets, and cache file signatures for efficiency.

New Features:

  • Add reload D-Bus method for automatic config reloading
  • Implement multi-level change detection using metadata timestamps and file signature comparison
  • Detect system time resets and clear caches to avoid missed updates

Enhancements:

  • Replace legacy trigger handler script with a streamlined reload handler
  • Improve config validation by monitoring entire config directories
  • Initialize and maintain file signature cache on startup

Build:

  • Install new reload handler script in CMake and remove old trigger handler option

Documentation:

  • Update Chinese and XML documentation to describe the new reload interface

@18202781743 18202781743 requested review from BLumia, mhduiy and zccrs July 1, 2025 06:30
@github-actions
Copy link

github-actions bot commented Jul 1, 2025

  • 检测到debian目录文件有变更: debian/dde-dconfig-daemon.postinst,debian/dde-dconfig-daemon.triggers,debian/rules

@github-actions github-actions bot requested a review from liujianqiang-niu July 1, 2025 06:30
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @18202781743 - I've reviewed your changes - here's some feedback:

  • detectChangedFiles() does a full recursive scan of all config directories on every reload—consider using QFileSystemWatcher or caching the file list between reloads to avoid performance hits in large directories.
  • The isSystemTimeReset() logic reads /proc/uptime and compares boot times, which can misinterpret suspend/resume or fail on non‐Linux platforms—consider using a monotonic clock (e.g. CLOCK_BOOTTIME or QElapsedTimer) for more reliable time-drift detection.
  • After removing the old isConfigurePath() logic, double-check that getAllConfigDirectories() still covers all your application-specific override paths to ensure no config files are inadvertently excluded from monitoring.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- detectChangedFiles() does a full recursive scan of all config directories on every reload—consider using QFileSystemWatcher or caching the file list between reloads to avoid performance hits in large directories.
- The isSystemTimeReset() logic reads /proc/uptime and compares boot times, which can misinterpret suspend/resume or fail on non‐Linux platforms—consider using a monotonic clock (e.g. CLOCK_BOOTTIME or QElapsedTimer) for more reliable time-drift detection.
- After removing the old isConfigurePath() logic, double-check that getAllConfigDirectories() still covers all your application-specific override paths to ensure no config files are inadvertently excluded from monitoring.

## Individual Comments

### Comment 1
<location> `dconfig-center/dde-dconfig-daemon/dconfigserver.cpp:556` </location>
<code_context>
+    QDateTime currentTime = QDateTime::currentDateTimeUtc();
+
+    // Check if system boot time changed (system reboot)
+    if (qAbs(currentBootTime.secsTo(m_systemBootTime)) > 60) {
+        qCInfo(cfLog()) << "System reboot detected, not a time reset";
+        return false; // System reboot, not time reset
</code_context>

<issue_to_address>
The 60-second threshold for system boot time difference may be too strict or too loose.

Since system clock drift or delays could affect this logic, consider making the threshold configurable or clearly documenting why 60 seconds was chosen.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    // Check if system boot time changed (system reboot)
    if (qAbs(currentBootTime.secsTo(m_systemBootTime)) > 60) {
        qCInfo(cfLog()) << "System reboot detected, not a time reset";
        return false; // System reboot, not time reset
    }
=======
    // Threshold (in seconds) for detecting system reboot via boot time change.
    // Default is 60 seconds to allow for minor clock drift or delays.
    static const int systemBootTimeThresholdSecs = 60; // TODO: Make configurable if needed

    // Check if system boot time changed (system reboot)
    if (qAbs(currentBootTime.secsTo(m_systemBootTime)) > systemBootTimeThresholdSecs) {
        qCInfo(cfLog()) << "System reboot detected, not a time reset";
        return false; // System reboot, not time reset
    }
>>>>>>> REPLACE

</suggested_fix>

### Comment 2
<location> `dconfig-center/dde-dconfig-daemon/dconfigserver.cpp:725` </location>
<code_context>
+    }
+
+    // Check file extension
+    if (!filePath.endsWith(".json")) {
+        return false;
+    }
</code_context>

<issue_to_address>
File extension check is case-sensitive.

Currently, files with uppercase extensions like ".JSON" will not be recognized. Normalize the extension to ensure case-insensitive matching if needed.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    // Check file extension
    if (!filePath.endsWith(".json")) {
        return false;
    }
=======
    // Check file extension (case-insensitive)
    if (!filePath.toLower().endsWith(".json")) {
        return false;
    }
>>>>>>> REPLACE

</suggested_fix>

### Comment 3
<location> `dconfig-center/dde-dconfig-daemon/dconfigserver.cpp:507` </location>
<code_context>
+ * 2. Signature verification: If time changed, verify with file signature comparison
+ * This prevents false positives from time inaccuracies while maintaining efficiency.
+ */
+void DSGConfigServer::reload()
+{
+    qCInfo(cfLog()) << "Reload configuration files";
</code_context>

<issue_to_address>
Consider moving all reload, scanning, and file signature logic into a separate ConfigReloadManager helper class to keep DSGConfigServer focused on core responsibilities.

```markdown
Consider pulling all of the “reload / scanning / signature / boot-time” logic out of DSGConfigServer into its own helper (e.g. `ConfigReloadManager`).  This keeps your core server class focused on D-Bus and resource management, and hides all the file-watching complexity behind a small, well-tested interface.

1. Create a new header `configreloadmanager.h`:
   ```cpp
   // configreloadmanager.h
   #pragma once
   #include <QObject>
   #include <QStringList>
   #include <QDateTime>

   class ConfigReloadManager : public QObject {
       Q_OBJECT
   public:
       explicit ConfigReloadManager(const QString &localPrefix, QObject *parent = nullptr);
       /// Initialize on startup (boots, initial signatures…)
       void initialize();
       /// Scans & returns a list of files that have changed since last reload
       QStringList reload();

   signals:
       /// Emitted when reload() finds one or more changed files
       void filesChanged(const QStringList &changedFiles);

   private:
       QString    m_localPrefix;
       QDateTime  m_startupTime;
       QDateTime  m_lastReloadTime;
       QMap<QString, FileSignature> m_fileSignatures;

       QDateTime getSystemBootTime() const;
       bool      isSystemTimeReset() const;
       QStringList getAllConfigDirectories() const;
       QStringList findConfigFiles(const QStringList &dirs) const;
       FileSignature getFileSignature(const QString &path) const;
       bool      isFileChanged(const FileSignature &, const FileSignature &, const QDateTime &) const;
   };
   ```

2. Move *all* of your `reload()`, `detectChangedFiles()`, `isSystemTimeReset()`, `getAllConfigDirectories()`, etc. into `ConfigReloadManager::reload()` and its private helpers.  The new `.cpp` is roughly your existing code, but now lives in one file.

3. In your `DSGConfigServer`:
   ```cpp
   // .h
   #include "configreloadmanager.h"
   class DSGConfigServer : public QObject {
       …
   private:
       ConfigReloadManager *m_reloadMgr;
   };

   // .cpp (in your initialize or constructor)
   m_reloadMgr = new ConfigReloadManager(m_localPrefix, this);
   m_reloadMgr->initialize();
   connect(m_reloadMgr, &ConfigReloadManager::filesChanged,
           this, &DSGConfigServer::onFilesChanged);
   ```

4. Delegate reload calls:
   ```cpp
   void DSGConfigServer::onFilesChanged(const QStringList &files) {
       for (auto &f : files)
           update(f);
   }

   // Whenever you want to trigger a manual reload:
   void DSGConfigServer::reload() {
       auto changed = m_reloadMgr->reload();
       if (!changed.isEmpty())
           emit m_reloadMgr->filesChanged(changed);
   }
   ```

Result:
- **DSGConfigServer** remains ~200 lines of D-Bus / resource logic.
- **ConfigReloadManager** encapsulates all scanning, timestamp, signature and boot-time logic.
- You can unit-test reload behavior in isolation and avoid mixing low-level FS code into your core server.
</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.

@sourcery-ai
Copy link

sourcery-ai bot commented Jul 1, 2025

Reviewer's Guide

This PR adds a new D-Bus reload interface with smart file detection—using multi-level checks (ctime + signature), system time reset handling, and signature caching—enhances directory scanning and validation, replaces the old trigger handler script, and updates related documentation.

Sequence diagram for the new D-Bus reload interface with smart config file detection

sequenceDiagram
    actor User
    participant DConfigClient as D-Bus Client
    participant DConfigServer as DSGConfigServer
    participant FileSystem

    User->>DConfigClient: Triggers reload (e.g., via dbus-send)
    DConfigClient->>DConfigServer: Call reload()
    DConfigServer->>DConfigServer: Check for system time reset
    DConfigServer->>DConfigServer: Scan config directories
    DConfigServer->>FileSystem: Get file metadata (ctime, size)
    DConfigServer->>DConfigServer: Compare with cached signatures
    alt Changed files detected
        DConfigServer->>DConfigServer: Call update(filePath) for each changed file
    end
    DConfigServer->>DConfigServer: Update last reload time and cache
    DConfigServer-->>DConfigClient: Return (void)
    DConfigClient-->>User: Reload complete
Loading

Class diagram for DSGConfigServer with reload and smart detection

classDiagram
    class DSGConfigServer {
        +void initialize()
        +void reload()
        +QDateTime getSystemBootTime() const
        +bool isSystemTimeReset() const
        +QStringList getAllConfigDirectories() const
        +QStringList findConfigFiles(const QStringList&) const
        +FileSignature getFileSignature(const QString&) const
        +QStringList detectChangedFiles() const
        +void initializeFileSignatures()
        +bool isFileChanged(const FileSignature&, const FileSignature&, const QDateTime&) const
        +bool isValidConfigFile(const QString&) const
        QDateTime m_startupTime
        QDateTime m_systemBootTime
        QDateTime m_lastReloadTime
        QMap<QString, FileSignature> m_fileSignatures
    }
    class FileSignature {
        qint64 size
        QDateTime changeTime
        QString filePath
        bool operator==(const FileSignature&) const
    }
    DSGConfigServer "1" o-- "*" FileSignature : m_fileSignatures
Loading

File-Level Changes

Change Details Files
Add reload D-Bus interface and initialization
  • Declared reload() slot and initialize() method in header
  • Registered reload method in service XML
  • Implemented initialize() to set startup and boot times
  • Invoked initialize() in main before event loop
dconfig-center/dde-dconfig-daemon/dconfigserver.h
dconfig-center/dde-dconfig-daemon/dconfigserver.cpp
dconfig-center/dde-dconfig-daemon/main.cpp
dconfig-center/dde-dconfig-daemon/services/org.desktopspec.ConfigManager.xml
Implement smart file detection with caching and time-reset handling
  • Added detectChangedFiles() and isFileChanged() for multi-level (ctime + size) checks
  • Implemented getFileSignature() and initializeFileSignatures() to cache signatures
  • Added getSystemBootTime() and isSystemTimeReset() to handle time jumps
  • Integrated reload() to process detected files and update last reload timestamp
dconfig-center/dde-dconfig-daemon/dconfigserver.cpp
dconfig-center/dde-dconfig-daemon/dconfigserver.h
Enhance config directory scanning and file validation
  • Introduced getAllConfigDirectories() and findConfigFiles() for recursive JSON discovery
  • Added isValidConfigFile() to filter by extension, readability, and monitored paths
dconfig-center/dde-dconfig-daemon/dconfigserver.cpp
dconfig-center/dde-dconfig-daemon/dconfigserver.h
Replace trigger handler script with new reload handler
  • Removed legacy dconfig-trigger-handler support
  • Installed dde-dconfig-daemon-reload-handler script via CMakeLists.txt
dconfig-center/dde-dconfig-daemon/CMakeLists.txt
dconfig-center/dde-dconfig-daemon/scripts/dconfig-trigger-handler
dconfig-center/dde-dconfig-daemon/scripts/dde-dconfig-daemon-reload-handler
Update documentation for new reload interface
  • Document reload method and features in Chinese markdown
  • Add reload method to D-Bus XML definitions
dconfig-center/docs/DtkConfig.zh_CN.md
dconfig-center/docs/org.desktopspec.ConfigManager.xml

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

@github-actions
Copy link

github-actions bot commented Jul 2, 2025

  • 检测到debian目录文件有变更: debian/dde-dconfig-daemon.postinst,debian/dde-dconfig-daemon.triggers,debian/rules

mhduiy
mhduiy previously approved these changes Jul 2, 2025
@github-actions
Copy link

github-actions bot commented Jul 2, 2025

  • 检测到debian目录文件有变更: debian/dde-dconfig-daemon.postinst,debian/dde-dconfig-daemon.triggers

@github-actions
Copy link

github-actions bot commented Jul 2, 2025

  • 检测到debian目录文件有变更: debian/dde-dconfig-daemon.postinst,debian/dde-dconfig-daemon.triggers

@github-actions
Copy link

github-actions bot commented Jul 3, 2025

  • 检测到debian目录文件有变更: debian/dde-dconfig-daemon.postinst,debian/dde-dconfig-daemon.triggers

@deepin-ci-robot
Copy link

deepin pr auto review

关键摘要:

  • dconfigserver.cpp中,reload函数中的diffConfigureFiles函数被调用两次,但只有一次是有效的,应该合并逻辑。
  • dconfigserver.cpp中的reload函数在处理文件变化时,没有对文件路径进行有效性检查,可能会导致错误处理。
  • dconfigserver.cpp中的allConfigureFileSignatures函数在处理目录时,没有对目录路径进行有效性检查,可能会导致错误处理。
  • dde-dconfig-daemon-reload-handler脚本中,call_dbus_reload函数在调用D-Bus方法时没有处理可能的错误,应该添加错误处理逻辑。
  • dde-dconfig-daemon-reload-handler脚本中,main函数在调用call_dbus_reload后没有检查返回值,应该添加错误处理逻辑。
  • dde-dconfig-daemon.postinst脚本中,triggered分支在调用dde-dconfig-daemon-reload-handler时没有处理可能的错误,应该添加错误处理逻辑。
  • dde-dconfig-daemon.triggers文件中,interest-noawait的使用可能不是预期的,应该确认这是否是正确的触发方式。

是否建议立即修改:

@github-actions
Copy link

github-actions bot commented Jul 3, 2025

  • 检测到debian目录文件有变更: debian/dde-dconfig-daemon.postinst,debian/dde-dconfig-daemon.triggers

@18202781743 18202781743 requested a review from zccrs July 3, 2025 05:25
zccrs
zccrs previously approved these changes Jul 3, 2025
1. Added new reload() method to detect and update changed config files
2. Implemented file signature tracking to detect actual changes
3. Replaced bash trigger handler with simpler reload handler
4. Added initialize() method to track initial file states
5. Updated D-Bus interface and documentation for new reload feature
6. Modified Debian triggers to use new reload mechanism

The changes improve configuration file change detection by:
- Using file metadata (size + change time) instead of timestamps
- Scanning all relevant config directories (including overrides)
- Only updating actually changed files
- Removing complex bash script in favor of native C++ implementation

feat: 实现配置文件重新加载机制

1. 新增reload()方法检测并更新变更的配置文件
2. 实现文件签名跟踪以检测实际变更
3. 用更简单的重载处理器替换bash触发器处理程序
4. 添加initialize()方法跟踪初始文件状态
5. 更新D-Bus接口和文档以支持新重载功能
6. 修改Debian触发器使用新重载机制

这些改进通过以下方式提升配置文件变更检测:
- 使用文件元数据(大小+变更时间)而非时间戳
- 扫描所有相关配置目录(包括覆盖目录)
- 仅更新实际变更的文件
- 移除复杂的bash脚本改用原生C++实现
@github-actions
Copy link

github-actions bot commented Jul 3, 2025

  • 检测到debian目录文件有变更: debian/dde-dconfig-daemon.postinst,debian/dde-dconfig-daemon.triggers

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, mhduiy

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

@18202781743 18202781743 merged commit 1bcbe73 into linuxdeepin:master Jul 3, 2025
19 of 20 checks passed
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