mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-08 02:52:07 +08:00
perf(backup): extract archive off the runtime
Run File::open, ZipArchive::new and the extraction of the backup archive inside spawn_blocking. Extracting a multi-file backup blocked a tokio worker for hundreds of milliseconds to seconds while the runtime kept serving other work on the remaining workers. Move the PROFILE_WRITE_LOCK acquisition after the extraction, right before finalize_restored_verge_config: the lock protects the config-data transition (extracted files reloaded into drafts), not the plain filesystem writes, so profile operations no longer queue behind the blocking unzip.
This commit is contained in:
@@ -161,10 +161,18 @@ pub async fn restore_webdav_backup(filename: String) -> Result<()> {
|
||||
})?;
|
||||
|
||||
let value = backup_storage_path.clone();
|
||||
let file = AsyncHandler::spawn_blocking(move || std::fs::File::open(&value)).await??;
|
||||
let mut zip = zip::ZipArchive::new(file)?;
|
||||
let home_dir = app_home_dir()?;
|
||||
AsyncHandler::spawn_blocking(move || -> Result<()> {
|
||||
let file = std::fs::File::open(&value)?;
|
||||
let mut zip = zip::ZipArchive::new(file)?;
|
||||
zip.extract(&home_dir)?;
|
||||
Ok(())
|
||||
})
|
||||
.await
|
||||
.map_err(|join| anyhow!("backup extraction task failed: {join}"))??;
|
||||
|
||||
// Held for the config-data transition only; extraction is plain filesystem work.
|
||||
let _profile_write = crate::config::profiles::PROFILE_WRITE_LOCK.lock().await;
|
||||
zip.extract(app_home_dir()?)?;
|
||||
let res = finalize_restored_verge_config(webdav_url, webdav_username, webdav_password).await;
|
||||
let _ = backup_storage_path.remove_if_exists().await;
|
||||
res
|
||||
@@ -344,10 +352,18 @@ pub async fn restore_local_backup(filename: String) -> Result<()> {
|
||||
)
|
||||
};
|
||||
|
||||
let file = AsyncHandler::spawn_blocking(move || std::fs::File::open(&target_path)).await??;
|
||||
let mut zip = zip::ZipArchive::new(file)?;
|
||||
let home_dir = app_home_dir()?;
|
||||
AsyncHandler::spawn_blocking(move || -> Result<()> {
|
||||
let file = std::fs::File::open(&target_path)?;
|
||||
let mut zip = zip::ZipArchive::new(file)?;
|
||||
zip.extract(&home_dir)?;
|
||||
Ok(())
|
||||
})
|
||||
.await
|
||||
.map_err(|join| anyhow!("backup extraction task failed: {join}"))??;
|
||||
|
||||
// Held for the config-data transition only; extraction is plain filesystem work.
|
||||
let _profile_write = crate::config::profiles::PROFILE_WRITE_LOCK.lock().await;
|
||||
zip.extract(app_home_dir()?)?;
|
||||
finalize_restored_verge_config(webdav_url, webdav_username, webdav_password).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user