diff --git a/infrastructure/src/official_update.rs b/infrastructure/src/official_update.rs index 2d3fadc..0ce9c08 100644 --- a/infrastructure/src/official_update.rs +++ b/infrastructure/src/official_update.rs @@ -1389,10 +1389,27 @@ impl OfficialUpdateService { let published_version_path = publish_layout .publish(&publish_plan) .map_err(anyhow::Error::msg)?; + // current symlink 已切换,资源发布成功。先取出完成版本记录并立即结束版本状态 + // 事务,使后续 snapshot / version-state 写入失败不会把这个已发布版本经 + // VersionStateGuard::Drop 误记为 failed,而是降级为可下轮重试的警告。 + let completed_record = version_state_guard.record()?.clone(); + version_state_guard.commit(); + let final_snapshot_path = snapshot_path_for(config, &published_version_path); - if config.snapshot_path.is_some() { - write_snapshot(&final_snapshot_path, ¤t_update_snapshot)?; - } + let snapshot_written = if config.snapshot_path.is_some() { + match write_snapshot(&final_snapshot_path, ¤t_update_snapshot) { + Ok(()) => true, + Err(error) => { + progress(OfficialUpdateProgress::new( + "publish", + format!("资源已发布,但写入最终 snapshot 失败(下轮可重试):{error}"), + )); + false + } + } + } else { + false + }; report.update_status = OfficialUpdateStatus::Downloaded; report.active_resource_root = published_version_path.clone(); @@ -1409,15 +1426,18 @@ impl OfficialUpdateService { report.local_manifest_verified_count = final_audit.verified_count(); report.local_manifest_repair_needed_count = final_audit.repair_needed_count(); report.verification_summary = final_verification_summary; - report.snapshot_written = Some(final_snapshot_path.clone()); - let completed_record = version_state_guard.record()?.clone(); - complete_version_state( + report.snapshot_written = snapshot_written.then(|| final_snapshot_path.clone()); + if let Err(error) = complete_version_state( &version_state_path, completed_record, &published_version_path, &final_snapshot_path, - )?; - version_state_guard.commit(); + ) { + progress(OfficialUpdateProgress::new( + "publish", + format!("资源已发布,但写入版本状态失败(下轮可重试):{error}"), + )); + } progress(OfficialUpdateProgress::new( "finish",