fix: synchronize plugin data phase initialization#3151
fix: synchronize plugin data phase initialization#315118202781743 merged 1 commit intolinuxdeepin:dcc-coredumpfrom
Conversation
Reviewer's GuideSynchronizes the plugin lifecycle so that the data phase starts only after all plugins have finished their module phase, using a new manager-level flag and coordination helpers wired into status updates and plugin loading flow. Sequence diagram for synchronized plugin data phase initializationsequenceDiagram
participant PluginManager
participant PluginDataA
participant PluginDataB
Note over PluginManager: Initial module loading for all plugins
PluginManager->>PluginDataA: start module phase
PluginManager->>PluginDataB: start module phase
Note over PluginDataA: PluginDataA finishes module phase first
PluginDataA-->>PluginManager: onUpdatePluginStatus(ModuleEnd)
PluginManager->>PluginManager: modulePhaseFinished(PluginDataA)
PluginManager->>PluginManager: allModulePhaseFinished() returns false
PluginManager->>PluginManager: tryStartDataPhase()
PluginManager-->>PluginManager: m_dataPhaseStarted is false and allModulePhaseFinished is false
PluginManager-->>PluginManager: return without starting data phase
Note over PluginDataB: PluginDataB finishes module phase later
PluginDataB-->>PluginManager: onUpdatePluginStatus(ModuleEnd)
PluginManager->>PluginManager: modulePhaseFinished(PluginDataB)
PluginManager->>PluginManager: allModulePhaseFinished() returns true
PluginManager->>PluginManager: tryStartDataPhase()
PluginManager->>PluginManager: set m_dataPhaseStarted to true
PluginManager->>PluginManager: for each plugin in m_plugins call loadPlugin(plugin)
loop for each plugin
PluginManager->>PluginDataA: loadPlugin(PluginDataA)
PluginManager->>PluginManager: branch on status (ModuleEnd, DataBegin, DataEnd)
PluginManager-->>PluginDataA: start data phase
PluginManager->>PluginDataB: loadPlugin(PluginDataB)
PluginManager->>PluginManager: branch on status (ModuleEnd, DataBegin, DataEnd)
PluginManager-->>PluginDataB: start data phase
end
Note over PluginManager: Later ModuleEnd or PluginEnd events will call tryStartDataPhase but m_dataPhaseStarted is true so no effect
Class diagram for PluginManager plugin phase coordinationclassDiagram
class PluginManager {
- QList~PluginData*~ m_plugins
- DccObject* m_rootModule
- QThreadPool* m_threadPool
- bool m_isDeleting
- bool m_dataPhaseStarted
- QQmlEngine* m_engine
+ PluginManager(DccManager* parent)
+ void loadModules(DccObject* root, bool async, QStringList dirs, QQmlEngine* engine)
+ void loadPlugin(PluginData* plugin)
+ void onUpdatePluginStatus(PluginData* plugin, uint status, QString log)
+ bool preparePluginFactory(PluginData* plugin)
+ bool updatePluginType(PluginData* plugin)
+ bool modulePhaseFinished(PluginData* plugin) const
+ bool allModulePhaseFinished() const
+ void tryStartDataPhase()
+ QThreadPool* threadPool()
}
class PluginData {
+ QString name
+ uint status
+ QObject* module
}
PluginManager "1" o-- "*" PluginData
PluginManager --> PluginData : monitors status and phases
PluginManager --> QThreadPool
PluginManager --> QQmlEngine
PluginManager --> DccObject
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 left some high level feedback:
- Given the async/thread-pool usage, accesses to m_dataPhaseStarted and iteration over m_plugins in allModulePhaseFinished()/tryStartDataPhase() should be reviewed for thread-safety (e.g. guarding with a mutex or ensuring these paths are only ever called on the main thread).
- modulePhaseFinished() returning true when plugin is nullptr is slightly surprising and could hide accidental null calls; consider either asserting non-null or keeping this helper private and only calling it from contexts where plugin is guaranteed to be valid.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Given the async/thread-pool usage, accesses to m_dataPhaseStarted and iteration over m_plugins in allModulePhaseFinished()/tryStartDataPhase() should be reviewed for thread-safety (e.g. guarding with a mutex or ensuring these paths are only ever called on the main thread).
- modulePhaseFinished() returning true when plugin is nullptr is slightly surprising and could hide accidental null calls; consider either asserting non-null or keeping this helper private and only calling it from contexts where plugin is guaranteed to be valid.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This PR updates the control-center plugin loading pipeline to synchronize the transition into the “data phase” so that no plugin starts createData() until all plugins have completed the module phase, avoiding interleaving module/data initialization across plugins.
Changes:
- Added
m_dataPhaseStartedto gate the data-phase transition. - Introduced
modulePhaseFinished(),allModulePhaseFinished(), andtryStartDataPhase()to coordinate starting the data phase across all plugins. - Updated
loadPlugin(),onUpdatePluginStatus(), andloadModules()to enforce the synchronized phase transition and reset state per load cycle.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/dde-control-center/pluginmanager.h |
Adds new helpers and the m_dataPhaseStarted flag to support synchronized phase transitions. |
src/dde-control-center/pluginmanager.cpp |
Implements synchronization logic and integrates it into the plugin status/update flow and module loading lifecycle. |
Changed plugin loading logic to ensure all plugins complete their module phase before any plugin starts the data phase. Previously, when a plugin reached ModuleEnd status, it would immediately proceed to LoadPluginTask for data loading. Now, the system waits until all plugins have finished their module phase (ModuleEnd, ModuleErr, or PluginEnd status) before starting data loading for any plugin. Key changes: 1. Added m_modulePhaseFinished flag to track module phase completion 2. Added allModulesFinished() method to check if all plugins have completed module phase 3. Added loadPluginData() method extracted from original loadPlugin() logic 4. Added onModulePhaseFinished() slot to handle transition to data phase 5. Modified loadPlugin() to check module phase completion before proceeding to data loading 6. Connected modulePhaseFinished signal to onModulePhaseFinished slot This ensures that plugins don't start their data loading (createData()) until all plugins have completed their module initialization, preventing potential race conditions and ensuring proper synchronization between plugins. Log: Fixed plugin loading synchronization issue Influence: 1. Test plugin loading with multiple plugins to ensure all complete module phase before data phase starts 2. Verify that plugins with ModuleEnd status wait for others before proceeding 3. Test edge cases where some plugins may have ModuleErr or PluginEnd status 4. Verify that the m_modulePhaseFinished flag is properly reset when needed 5. Test plugin loading performance to ensure no regression 6. Verify that hidden plugins (not visibleToApp) still follow the synchronization logic fix: 同步插件数据阶段加载 修改插件加载逻辑,确保所有插件完成模块阶段后再开始数据阶段。之前,当插件 达到 ModuleEnd 状态时,会立即进入 LoadPluginTask 进行数据加载。现在,系 统会等待所有插件完成模块阶段(ModuleEnd、ModuleErr 或 PluginEnd 状态)后 才开始任何插件的数据加载。 主要变更: 1. 添加 m_modulePhaseFinished 标志来跟踪模块阶段完成状态 2. 添加 allModulesFinished() 方法来检查所有插件是否已完成模块阶段 3. 添加 loadPluginData() 方法,从原始 loadPlugin() 逻辑中提取 4. 添加 onModulePhaseFinished() 槽函数来处理向数据阶段的过渡 5. 修改 loadPlugin() 以在进入数据加载前检查模块阶段完成状态 6. 连接 modulePhaseFinished 信号到 onModulePhaseFinished 槽 这确保了插件在所有插件完成模块初始化之前不会开始数据加载 (createData()),防止潜在的竞争条件并确保插件之间的正确同步。 Log: 修复插件加载同步问题 Influence: 1. 测试多插件加载,确保所有插件在数据阶段开始前完成模块阶段 2. 验证具有 ModuleEnd 状态的插件在继续之前会等待其他插件 3. 测试某些插件可能具有 ModuleErr 或 PluginEnd 状态的边缘情况 4. 验证 m_modulePhaseFinished 标志在需要时正确重置 5. 测试插件加载性能,确保没有回归问题 6. 验证隐藏插件(不可见)仍然遵循同步逻辑
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 18202781743, caixr23 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 |
This change ensures that all plugins complete their module phase before any plugin enters the data phase. Previously, when a single plugin reached ModuleEnd, it would immediately proceed to createData(), potentially causing issues if other plugins were still in their module phase. Now the system waits for all plugins to finish their module phase before starting the data phase for any plugin, ensuring proper synchronization.
Log: Fixed plugin loading synchronization issue
Influence:
fix: 同步插件数据阶段初始化
此更改确保所有插件完成其模块阶段后,任何插件才能进入数据阶段。之前,当单
个插件达到 ModuleEnd 时,它会立即进入 createData(),如果其他插件仍处于模
块阶段,可能会导致问题。现在系统会等待所有插件完成模块阶段,然后才开始任
何插件的数据阶段,确保适当的同步。
Log: 修复插件加载同步问题
Influence:
Summary by Sourcery
Synchronize the transition from plugin module phase to data phase so that data loading only begins once all plugins have completed their module phase.
Bug Fixes:
Enhancements: