diff --git a/app/runtime/extensions/plugin/registry.py b/app/runtime/extensions/plugin/registry.py index b94a0b3f0..56e21adbf 100644 --- a/app/runtime/extensions/plugin/registry.py +++ b/app/runtime/extensions/plugin/registry.py @@ -41,11 +41,15 @@ class PluginRegistry: def plugin_ids(self) -> list[str]: """返回保持登记顺序的插件类 ID 快照。""" - return list(self._classes) + return list(self.classes_snapshot()) def running_ids(self) -> list[str]: """返回保持登记顺序的运行实例 ID 快照。""" - return list(self._running) + return list(self.running_snapshot()) + + def classes_snapshot(self) -> Dict[str, Any]: + """复制插件类表,避免插件重载期间迭代失效。""" + return dict(self._classes) def running_snapshot(self) -> Dict[str, Any]: """复制运行实例表,避免插件重载期间迭代失效。""" diff --git a/app/runtime/extensions/plugin/runtime.py b/app/runtime/extensions/plugin/runtime.py index b1d780632..dea6d15da 100644 --- a/app/runtime/extensions/plugin/runtime.py +++ b/app/runtime/extensions/plugin/runtime.py @@ -244,7 +244,7 @@ def build_plugin_runtime( log=environment.logger, ) catalog = PluginCatalogFacade( - classes=lambda: registry.classes, + classes=registry.classes_snapshot, running=lambda: registry.running, storage=environment.storage, system=environment.system, diff --git a/tests/test_plugin_registry.py b/tests/test_plugin_registry.py index f2a18eab3..5439e8095 100644 --- a/tests/test_plugin_registry.py +++ b/tests/test_plugin_registry.py @@ -12,14 +12,20 @@ def test_registry_owns_classes_instances_and_stable_snapshots(): registry.classes["Demo"] = plugin_class registry.running["Demo"] = plugin_instance + classes_snapshot = registry.classes_snapshot() snapshot = registry.running_snapshot() - registry.running["Other"] = SimpleNamespace(plugin_name="其它") assert registry.has_class("Demo") assert registry.plugin_class("Demo") is plugin_class assert registry.instance("Demo") is plugin_instance assert registry.plugin_ids() == ["Demo"] + assert registry.running_ids() == ["Demo"] + + registry.classes["Other"] = type("Other", (), {}) + registry.running["Other"] = SimpleNamespace(plugin_name="其它") + assert registry.running_ids() == ["Demo", "Other"] + assert list(classes_snapshot) == ["Demo"] assert list(snapshot) == ["Demo"]