Fix/impl refactor (#14776)

* fix: impl refactor

* fix: unload/load python module, race conditions, freezes

* remove dead code

* remove extra hook

* remove more dead code

* fix gil run script
This commit is contained in:
Ian Chua
2026-07-15 20:12:51 +08:00
committed by GitHub
parent 1551898846
commit 62afea225a
35 changed files with 4162 additions and 3373 deletions

View File

@@ -1,11 +1,14 @@
#include "PluginFsUtils.hpp"
#include "PythonFileUtils.hpp"
#include "libslic3r/Utils.hpp"
#include <boost/filesystem.hpp>
#include <boost/log/trivial.hpp>
#include <chrono>
#include <filesystem>
#include <utility>
#include "PluginAuditManager.hpp"
@@ -107,4 +110,148 @@ bool delete_plugin_root(const boost::filesystem::path& resolved_root,
return true;
}
// ── Discovery ───────────────────────────────────────────────────────────────────────────────
namespace {
// Derive a discovered descriptor's operational plugin_key: the cloud UUID for cloud entries,
// otherwise the (escaped) stem of name_source (the entry file when one exists, or the plugin
// directory when it does not). plugin_key is always derived, never read back from the sidecar.
void assign_discovered_plugin_key(PluginDescriptor& descriptor, const boost::filesystem::path& name_source)
{
if (descriptor.is_cloud_plugin())
descriptor.plugin_key = descriptor.cloud_uuid();
else
descriptor.plugin_key = make_local_plugin_key(name_source.stem().string());
}
void scan_plugin_directory(const std::string& dir_path, std::vector<PluginDescriptor>& out)
{
namespace fs = boost::filesystem;
if (!fs::exists(dir_path) || !fs::is_directory(dir_path))
return;
BOOST_LOG_TRIVIAL(debug) << "Scanning plugin directory: " << dir_path;
try {
for (fs::directory_iterator it(dir_path); it != fs::directory_iterator(); ++it) {
if (!fs::is_directory(it->status()))
continue;
const fs::path plugin_dir = it->path();
if (is_ignored_plugin_directory(plugin_dir))
continue;
PluginDescriptor descriptor;
descriptor.plugin_root = plugin_dir.string();
std::string entry_error;
const fs::path entry_path = find_installed_plugin_entry(plugin_dir, entry_error);
// No usable entry file: keep the package as an invalid row so the UI can show it and
// its error, rather than dropping it silently.
if (entry_path.empty()) {
descriptor.set_error(entry_error);
read_install_state(plugin_dir, descriptor);
assign_discovered_plugin_key(descriptor, plugin_dir);
out.push_back(std::move(descriptor));
BOOST_LOG_TRIVIAL(warning) << "Invalid plugin package: " << plugin_dir.string() << " - " << out.back().error;
continue;
}
std::string meta_error;
const bool is_wheel = entry_path.extension() == ".whl";
const bool parsed = is_wheel ? read_wheel_plugin_metadata(entry_path, descriptor, meta_error) :
read_python_plugin_metadata(entry_path, descriptor, meta_error);
if (!parsed) {
descriptor.set_error(meta_error);
read_install_state(plugin_dir, descriptor);
assign_discovered_plugin_key(descriptor, entry_path);
out.push_back(std::move(descriptor));
BOOST_LOG_TRIVIAL(warning) << (is_wheel ? "Invalid wheel plugin: " : "Invalid .py plugin: ")
<< plugin_dir.string() << " - " << out.back().error;
continue;
}
descriptor.entry_path = entry_path.string();
descriptor.set_metadata_valid(true);
descriptor.clear_error();
// Cloud identity and the package-level auto-load flag. plugin_key is always derived
// below, never read from the sidecar.
read_install_state(plugin_dir, descriptor);
assign_discovered_plugin_key(descriptor, entry_path);
out.push_back(std::move(descriptor));
BOOST_LOG_TRIVIAL(info) << "Discovered plugin: " << out.back().name << " (version: " << out.back().version << ")";
}
} catch (const std::exception& ex) {
BOOST_LOG_TRIVIAL(error) << "Error scanning directory " << dir_path << ": " << ex.what();
}
}
} // namespace
std::vector<std::string> get_plugin_directories(const std::string& cloud_user_id)
{
namespace fs = boost::filesystem;
std::vector<std::string> dirs;
// Creates the directory when missing — callers (notably the install path) rely on it existing.
auto add_or_create_dir = [&dirs](const fs::path& path) {
if (fs::exists(path) && fs::is_directory(path)) {
dirs.push_back(path.string());
return;
}
try {
fs::create_directories(path);
dirs.push_back(path.string());
BOOST_LOG_TRIVIAL(info) << "Created plugin directory: " << path.string();
} catch (const std::exception& ex) {
BOOST_LOG_TRIVIAL(warning) << "Failed to create plugin directory: " << ex.what();
}
};
// Local plugins: {data_dir}/orca_plugins/
add_or_create_dir(fs::path(data_dir()) / "orca_plugins");
// Cloud plugins: {data_dir}/orca_plugins/_subscribed/{user_id}/
if (!cloud_user_id.empty())
add_or_create_dir(fs::path(get_cloud_plugin_dir(cloud_user_id)));
return dirs;
}
std::vector<PluginDescriptor> discover_plugin_packages(const std::vector<std::string>& dirs, std::string& error)
{
error.clear();
const auto start_time = std::chrono::steady_clock::now();
std::vector<PluginDescriptor> discovered;
try {
BOOST_LOG_TRIVIAL(info) << "Scanning " << dirs.size() << " plugin directories...";
for (const std::string& dir : dirs)
scan_plugin_directory(dir, discovered);
const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time);
BOOST_LOG_TRIVIAL(info) << "Plugin discovery completed in " << duration.count() << "ms. Found " << discovered.size()
<< " plugin manifests";
} catch (const std::exception& ex) {
error = std::string("Plugin discovery failed: ") + ex.what();
BOOST_LOG_TRIVIAL(error) << error;
} catch (...) {
error = "Plugin discovery failed: unknown error";
BOOST_LOG_TRIVIAL(error) << error;
}
return discovered;
}
} // namespace Slic3r