mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2026-01-29 12:20:50 -07:00
Improve hot reload plugin
This commit is contained in:
parent
01f5c4caaa
commit
b908c33eea
2 changed files with 94 additions and 12 deletions
|
|
@ -1524,7 +1524,7 @@ int GUI_App::install_plugin(std::string name, std::string package_name, InstallP
|
|||
app_config->set_network_plugin_version(config_version);
|
||||
GUI::wxGetApp().CallAfter([this] {
|
||||
if (app_config)
|
||||
app_config->save();
|
||||
app_config->save();
|
||||
});
|
||||
}
|
||||
if (!config_version.empty() && boost::filesystem::exists(legacy_lib_path)) {
|
||||
|
|
@ -1643,6 +1643,70 @@ void GUI_App::restart_networking()
|
|||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(" exit, m_agent=%1%")%m_agent;
|
||||
}
|
||||
|
||||
// Network plugin hot reload timeout constants (in milliseconds)
|
||||
namespace {
|
||||
constexpr int CALLBACK_DRAIN_TIMEOUT_MS = 200; // Time to drain pending CallAfter callbacks
|
||||
constexpr int NETWORK_IDLE_TIMEOUT_MS = 500; // Max wait for network operations to complete
|
||||
constexpr int FINAL_DRAIN_TIMEOUT_MS = 100; // Final event processing before destruction
|
||||
constexpr int POLL_INTERVAL_MS = 50; // Polling interval for state checks
|
||||
constexpr int MAX_YIELD_ITERATIONS = 20; // Maximum wxYield calls per drain cycle
|
||||
}
|
||||
|
||||
// Process pending wx events with bounded iteration count
|
||||
void GUI_App::drain_pending_events(int timeout_ms)
|
||||
{
|
||||
const auto deadline = std::chrono::steady_clock::now() +
|
||||
std::chrono::milliseconds(timeout_ms);
|
||||
int yield_count = 0;
|
||||
|
||||
while (std::chrono::steady_clock::now() < deadline) {
|
||||
// Process pending events
|
||||
if (wxTheApp) {
|
||||
wxTheApp->ProcessPendingEvents();
|
||||
}
|
||||
|
||||
// Bounded wxYield to prevent infinite loops
|
||||
if (yield_count < MAX_YIELD_ITERATIONS) {
|
||||
wxYield();
|
||||
++yield_count;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(POLL_INTERVAL_MS));
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for network operations to complete with state verification
|
||||
bool GUI_App::wait_for_network_idle(int timeout_ms)
|
||||
{
|
||||
const auto deadline = std::chrono::steady_clock::now() +
|
||||
std::chrono::milliseconds(timeout_ms);
|
||||
|
||||
while (std::chrono::steady_clock::now() < deadline) {
|
||||
if (!m_agent) {
|
||||
return true; // Agent already gone
|
||||
}
|
||||
|
||||
// Verify all operations completed
|
||||
bool server_disconnected = !m_agent->is_server_connected();
|
||||
|
||||
if (server_disconnected) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": network is idle";
|
||||
return true;
|
||||
}
|
||||
|
||||
// Process events while waiting
|
||||
if (wxTheApp) {
|
||||
wxTheApp->ProcessPendingEvents();
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(POLL_INTERVAL_MS));
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": timeout after " << timeout_ms
|
||||
<< "ms, server_connected=" << (m_agent ? m_agent->is_server_connected() : false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GUI_App::hot_reload_network_plugin()
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": starting hot reload";
|
||||
|
|
@ -1671,8 +1735,8 @@ bool GUI_App::hot_reload_network_plugin()
|
|||
}
|
||||
|
||||
if (m_agent) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": clearing callbacks and stopping operations";
|
||||
|
||||
// Phase 1: Clear all callbacks (stops new invocations)
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 1 - clearing callbacks";
|
||||
m_agent->set_on_ssdp_msg_fn(nullptr);
|
||||
m_agent->set_on_user_login_fn(nullptr);
|
||||
m_agent->set_on_printer_connected_fn(nullptr);
|
||||
|
|
@ -1685,23 +1749,39 @@ bool GUI_App::hot_reload_network_plugin()
|
|||
m_agent->set_on_local_message_fn(nullptr);
|
||||
m_agent->set_queue_on_main_fn(nullptr);
|
||||
|
||||
m_agent->start_discovery(false, false);
|
||||
m_agent->disconnect_printer();
|
||||
// Phase 2: Drain pending CallAfter callbacks (bounded)
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 2 - draining callbacks";
|
||||
drain_pending_events(CALLBACK_DRAIN_TIMEOUT_MS);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
// Phase 3: Stop operations and verify return values
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 3 - stopping operations";
|
||||
bool discovery_stopped = m_agent->start_discovery(false, false);
|
||||
int disconnect_result = m_agent->disconnect_printer();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": discovery_stopped=" << discovery_stopped
|
||||
<< ", disconnect_result=" << disconnect_result;
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": destroying network agent";
|
||||
// Phase 4: Wait for idle with state verification
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 4 - waiting for idle";
|
||||
bool became_idle = wait_for_network_idle(NETWORK_IDLE_TIMEOUT_MS);
|
||||
if (!became_idle) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": proceeding despite timeout";
|
||||
}
|
||||
|
||||
// Phase 5: Final bounded drain before destruction
|
||||
drain_pending_events(FINAL_DRAIN_TIMEOUT_MS);
|
||||
|
||||
// Phase 6: Destroy agent
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 6 - destroying agent";
|
||||
delete m_agent;
|
||||
m_agent = nullptr;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
||||
}
|
||||
|
||||
// Phase 7: Unload module
|
||||
if (Slic3r::NetworkAgent::is_network_module_loaded()) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": unloading old module";
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": Phase 7 - unloading module";
|
||||
drain_pending_events(FINAL_DRAIN_TIMEOUT_MS);
|
||||
int unload_result = Slic3r::NetworkAgent::unload_network_module();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": unload result = " << unload_result;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": unload_result=" << unload_result;
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": calling restart_networking";
|
||||
|
|
|
|||
|
|
@ -703,6 +703,8 @@ private:
|
|||
void init_networking_callbacks();
|
||||
void init_app_config();
|
||||
void remove_old_networking_plugins();
|
||||
void drain_pending_events(int timeout_ms);
|
||||
bool wait_for_network_idle(int timeout_ms);
|
||||
//BBS set extra header for http request
|
||||
std::map<std::string, std::string> get_extra_header();
|
||||
void init_http_extra_header();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue