From 4d818f512c60ef3e7e4037af04f2b6836b2af783 Mon Sep 17 00:00:00 2001 From: Yuyi-Oak <1722157266@qq.com> Date: Thu, 16 Jul 2026 07:17:51 -0700 Subject: [PATCH] =?UTF-8?q?fix(official-sync):=20=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E5=90=8E=E7=AB=8B=E5=8D=B3=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=8A=B6=E6=80=81=E4=BA=8B=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit publish() 切换 current symlink 后,写最终 snapshot 或 complete_version_state 若失败会经 ? 提前返回,此时 VersionStateGuard 尚未 commit,其 Drop 会把这个 磁盘上已发布(current 已指向)的版本记入 failed_versions,造成状态与磁盘不一致。 改为在 publish() 成功后立即取出完成记录并 commit 版本状态事务,随后 snapshot 与 version-state 写入失败降级为可下轮重试的警告(不再 ? 中断、不再误记 failed); snapshot_written 也改为仅在实际写入成功时置 Some。 对应 issue #18 维护清单 1-3。 Co-Authored-By: Claude Fable 5 --- infrastructure/src/official_update.rs | 36 +++++++++++++++++++++------ 1 file changed, 28 insertions(+), 8 deletions(-) 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",