mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-17 08:36:26 +03: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()
|
||||
{
|
||||
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!");
|
||||
}
|
||||
|
||||
// The config is first written to a file with a PID suffix and then moved
|
||||
// to avoid race conditions with multiple instances of Slic3r
|
||||
|
||||
@@ -5782,7 +5782,10 @@ void GUI_App::reload_settings()
|
||||
load_pending_vendors();
|
||||
preset_bundle->load_user_presets(*app_config, user_presets, ForwardCompatibilitySubstitutionRule::Enable);
|
||||
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;
|
||||
|
||||
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_filaments.clear();
|
||||
}
|
||||
@@ -6508,36 +6513,29 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg)
|
||||
cancelFn = [this, dlg]() {
|
||||
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) {
|
||||
CallAfter([=]{
|
||||
dlg->Destroy();
|
||||
if (ok && m_agent && t.lock() == m_user_sync_token && userid == m_agent->get_user_id()) reload_settings();
|
||||
});
|
||||
finishFn = [this, dlg](bool) {
|
||||
CallAfter([=]{ dlg->Destroy(); });
|
||||
};
|
||||
}
|
||||
else {
|
||||
finishFn = [this, userid = m_agent->get_user_id(), t = std::weak_ptr<int>(m_user_sync_token)](bool ok) {
|
||||
CallAfter([=] {
|
||||
if (ok && m_agent && t.lock() == m_user_sync_token && userid == m_agent->get_user_id()) reload_settings();
|
||||
});
|
||||
};
|
||||
finishFn = [](bool) {}; // reload_settings() is now triggered from the background thread
|
||||
cancelFn = [this]() {
|
||||
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);
|
||||
|
||||
m_sync_update_thread = Slic3r::create_thread(
|
||||
[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
|
||||
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
|
||||
// So that we can sync presets that are migrated from old version or users manually put preset files in preset folder
|
||||
@@ -6562,9 +6560,12 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg)
|
||||
}
|
||||
}, progressFn, cancelFn);
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " get_setting_list2 ret = " << ret << " m_is_closing = " << m_is_closing;
|
||||
|
||||
|
||||
finishFn(ret == 0);
|
||||
|
||||
if (ret == 0 && m_agent && !t.expired())
|
||||
reload_settings();
|
||||
|
||||
// For orca specific syncing
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user