将自动切分状态写盘移出 Tokio worker
用 spawn_blocking 承载 JSON 序列化和文件写入,并在工作流中等待结果。
This commit is contained in:
+7
-1
@@ -42,7 +42,13 @@ pub fn project_relative_path(root: &Path, path: &Path) -> Result<String, String>
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn write_separation_state(path: &Path, state: &SeparationState) -> Result<(), String> {
|
||||
pub async fn write_separation_state(path: PathBuf, state: SeparationState) -> Result<(), String> {
|
||||
tokio::task::spawn_blocking(move || write_separation_state_blocking(&path, &state))
|
||||
.await
|
||||
.map_err(|error| format!("写入 separation state 任务失败:{error}"))?
|
||||
}
|
||||
|
||||
fn write_separation_state_blocking(path: &Path, state: &SeparationState) -> Result<(), String> {
|
||||
if state.schema_version != SEPARATION_STATE_SCHEMA_VERSION {
|
||||
app_log!("ui_separation.error stage=state_write reason=schema_mismatch");
|
||||
return Err("不支持的 separation state schema".to_string());
|
||||
|
||||
+14
-12
@@ -98,13 +98,15 @@ pub(crate) async fn separate_ui_impl(
|
||||
image.pixel_size.x.round() as u32,
|
||||
image.pixel_size.y.round() as u32
|
||||
);
|
||||
write_separation_state(&state_path, &separation).map_err(|error| {
|
||||
app_log!(
|
||||
"ui_separation.error stage=state_checkpoint tree_index={} error={error}",
|
||||
tree_index
|
||||
);
|
||||
error
|
||||
})?;
|
||||
write_separation_state(state_path.clone(), separation.clone())
|
||||
.await
|
||||
.map_err(|error| {
|
||||
app_log!(
|
||||
"ui_separation.error stage=state_checkpoint tree_index={} error={error}",
|
||||
tree_index
|
||||
);
|
||||
error
|
||||
})?;
|
||||
let mut batch_index = 0usize;
|
||||
loop {
|
||||
let batch_started = Instant::now();
|
||||
@@ -146,7 +148,7 @@ pub(crate) async fn separate_ui_impl(
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
app_log!("ui_separation.error stage=image_edit tree_index={} batch_index={} error={error}", tree_index, batch_index);
|
||||
write_separation_state(&state_path, &separation)?;
|
||||
write_separation_state(state_path.clone(), separation.clone()).await?;
|
||||
return Err(error);
|
||||
}
|
||||
};
|
||||
@@ -155,7 +157,7 @@ pub(crate) async fn separate_ui_impl(
|
||||
extract::write_processed_image(processed_url.clone(), processed_path.clone()).await
|
||||
{
|
||||
app_log!("ui_separation.error stage=processed_image_write tree_index={} batch_index={} error={error}", tree_index, batch_index);
|
||||
write_separation_state(&state_path, &separation)?;
|
||||
write_separation_state(state_path.clone(), separation.clone()).await?;
|
||||
return Err(error);
|
||||
}
|
||||
let binding = match binding::visual_binding(
|
||||
@@ -169,7 +171,7 @@ pub(crate) async fn separate_ui_impl(
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
app_log!("ui_separation.error stage=visual_binding tree_index={} batch_index={} error={error}", tree_index, batch_index);
|
||||
write_separation_state(&state_path, &separation)?;
|
||||
write_separation_state(state_path.clone(), separation.clone()).await?;
|
||||
return Err(error);
|
||||
}
|
||||
};
|
||||
@@ -220,11 +222,11 @@ pub(crate) async fn separate_ui_impl(
|
||||
}
|
||||
if let Some(error) = cut_error {
|
||||
app_log!("ui_separation.error stage=cut_batch tree_index={} batch_index={} error={error}", tree_index, batch_index);
|
||||
write_separation_state(&state_path, &separation)?;
|
||||
write_separation_state(state_path.clone(), separation.clone()).await?;
|
||||
return Err(error);
|
||||
}
|
||||
patch::apply_batch_patch(&mut separation, tree_index, &binding.decisions, &cut_paths)?;
|
||||
write_separation_state(&state_path, &separation)?;
|
||||
write_separation_state(state_path.clone(), separation.clone()).await?;
|
||||
app_log!(
|
||||
"ui_separation.batch_completed tree_index={} batch_index={} cuts={} bound={} problematic={} elapsed_ms={}",
|
||||
tree_index, batch_index, cut_paths.len(), separation.bound.len(), separation.problematic_nodes.len(), batch_started.elapsed().as_millis()
|
||||
|
||||
Reference in New Issue
Block a user