mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-20 11:53:48 +00:00
Enhancement: eliminate UI freeze during cloud preset sync on startup (#13673)
fix: eliminate UI freeze during cloud preset sync on startup
Move synchronous HTTP calls off the main thread in
GUI_App::start_sync_user_preset():
- Call scan_orphaned_info_files() and process_delete_presets() in
the background sync thread instead of the UI thread, so their
HTTP DELETE calls don't block startup.
- Call reload_settings() directly from the background thread
instead of via CallAfter, so get_user_presets() (HTTP GET) and
load/save_user_presets (file I/O) run off the main thread.
- Guard update_side_preset_ui() and app_config->save() with
is_main_thread_active() / CallAfter so they're safe when called
from a worker thread.
- Simplifiy finishFn lambdas: the progress-dialog case only
destroys the dialog; the no-dialog case is a no-op.
This commit is contained in:
@@ -834,8 +834,10 @@ std::string AppConfig::load()
|
|||||||
|
|
||||||
void AppConfig::save()
|
void AppConfig::save()
|
||||||
{
|
{
|
||||||
if (! is_main_thread_active())
|
if (!is_main_thread_active()) {
|
||||||
|
BOOST_LOG_TRIVIAL(fatal) << "Calling AppConfig::save() from a worker thread!";
|
||||||
throw CriticalException("Calling AppConfig::save() from a worker thread!");
|
throw CriticalException("Calling AppConfig::save() from a worker thread!");
|
||||||
|
}
|
||||||
|
|
||||||
// The config is first written to a file with a PID suffix and then moved
|
// The config is first written to a file with a PID suffix and then moved
|
||||||
// to avoid race conditions with multiple instances of Slic3r
|
// to avoid race conditions with multiple instances of Slic3r
|
||||||
|
|||||||
@@ -5782,7 +5782,10 @@ void GUI_App::reload_settings()
|
|||||||
load_pending_vendors();
|
load_pending_vendors();
|
||||||
preset_bundle->load_user_presets(*app_config, user_presets, ForwardCompatibilitySubstitutionRule::Enable);
|
preset_bundle->load_user_presets(*app_config, user_presets, ForwardCompatibilitySubstitutionRule::Enable);
|
||||||
preset_bundle->save_user_presets(*app_config, get_delete_cache_presets());
|
preset_bundle->save_user_presets(*app_config, get_delete_cache_presets());
|
||||||
mainframe->update_side_preset_ui();
|
if (is_main_thread_active())
|
||||||
|
mainframe->update_side_preset_ui();
|
||||||
|
else
|
||||||
|
CallAfter([this] { mainframe->update_side_preset_ui(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6023,8 +6026,10 @@ void GUI_App::load_pending_vendors()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
preset_bundle->apply_vendor_config(need_add_vendors, need_add_filaments, app_config, false);
|
preset_bundle->apply_vendor_config(need_add_vendors, need_add_filaments, app_config, false);
|
||||||
app_config->save();
|
if (is_main_thread_active())
|
||||||
|
app_config->save();
|
||||||
|
else
|
||||||
|
CallAfter([this] { app_config->save(); });
|
||||||
need_add_vendors.clear();
|
need_add_vendors.clear();
|
||||||
need_add_filaments.clear();
|
need_add_filaments.clear();
|
||||||
}
|
}
|
||||||
@@ -6508,36 +6513,29 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg)
|
|||||||
cancelFn = [this, dlg]() {
|
cancelFn = [this, dlg]() {
|
||||||
return is_closing() || dlg->WasCanceled();
|
return is_closing() || dlg->WasCanceled();
|
||||||
};
|
};
|
||||||
finishFn = [this, userid = m_agent->get_user_id(), dlg, t = std::weak_ptr<int>(m_user_sync_token)](bool ok) {
|
finishFn = [this, dlg](bool) {
|
||||||
CallAfter([=]{
|
CallAfter([=]{ dlg->Destroy(); });
|
||||||
dlg->Destroy();
|
|
||||||
if (ok && m_agent && t.lock() == m_user_sync_token && userid == m_agent->get_user_id()) reload_settings();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
finishFn = [this, userid = m_agent->get_user_id(), t = std::weak_ptr<int>(m_user_sync_token)](bool ok) {
|
finishFn = [](bool) {}; // reload_settings() is now triggered from the background thread
|
||||||
CallAfter([=] {
|
|
||||||
if (ok && m_agent && t.lock() == m_user_sync_token && userid == m_agent->get_user_id()) reload_settings();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
cancelFn = [this]() {
|
cancelFn = [this]() {
|
||||||
return is_closing();
|
return is_closing();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do a one-time scan for files that may be pending deletion (e.g., was deleted while not connected to internet)
|
|
||||||
// Scan for orphaned .info files on startup and add them to deletion queue
|
|
||||||
scan_orphaned_info_files();
|
|
||||||
process_delete_presets();
|
|
||||||
|
|
||||||
Bind(EVT_UPDATE_PRESET_BUNDLE,&GUI_App::update_single_bundle,this);
|
Bind(EVT_UPDATE_PRESET_BUNDLE,&GUI_App::update_single_bundle,this);
|
||||||
|
|
||||||
m_sync_update_thread = Slic3r::create_thread(
|
m_sync_update_thread = Slic3r::create_thread(
|
||||||
[this, progressFn, cancelFn, finishFn, t = std::weak_ptr<int>(m_user_sync_token)] {
|
[this, progressFn, cancelFn, finishFn, t = std::weak_ptr<int>(m_user_sync_token)] {
|
||||||
|
if (!m_agent) return;
|
||||||
|
|
||||||
|
// One-time scan for orphaned .info files left over from offline deletions; queues HTTP DELETEs.
|
||||||
|
scan_orphaned_info_files();
|
||||||
|
process_delete_presets();
|
||||||
|
|
||||||
// get setting list, update setting list
|
// get setting list, update setting list
|
||||||
std::string version = preset_bundle->get_vendor_profile_version(PresetBundle::ORCA_DEFAULT_BUNDLE).to_string();
|
std::string version = preset_bundle->get_vendor_profile_version(PresetBundle::ORCA_DEFAULT_BUNDLE).to_string();
|
||||||
if(!m_agent) return;
|
|
||||||
|
|
||||||
// run check_and_fix_user_presets_syncinfo once before syncing to make sure all presets have correct sync_info
|
// run check_and_fix_user_presets_syncinfo once before syncing to make sure all presets have correct sync_info
|
||||||
// So that we can sync presets that are migrated from old version or users manually put preset files in preset folder
|
// So that we can sync presets that are migrated from old version or users manually put preset files in preset folder
|
||||||
@@ -6565,6 +6563,9 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg)
|
|||||||
|
|
||||||
finishFn(ret == 0);
|
finishFn(ret == 0);
|
||||||
|
|
||||||
|
if (ret == 0 && m_agent && !t.expired())
|
||||||
|
reload_settings();
|
||||||
|
|
||||||
// For orca specific syncing
|
// For orca specific syncing
|
||||||
auto orca_agent = std::dynamic_pointer_cast<OrcaCloudServiceAgent>(m_agent->get_cloud_agent());
|
auto orca_agent = std::dynamic_pointer_cast<OrcaCloudServiceAgent>(m_agent->get_cloud_agent());
|
||||||
int tick_tock = -1, sync_count = 0; // tick_tock = -1 to immediately run sync the frist time this thread runs
|
int tick_tock = -1, sync_count = 0; // tick_tock = -1 to immediately run sync the frist time this thread runs
|
||||||
|
|||||||
Reference in New Issue
Block a user