mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-07-22 06:28:00 +08:00
fix(daemon): 去重失败版本并优化状态输出
This commit is contained in:
@@ -1967,11 +1967,12 @@ fn recover_interrupted_version_state(path: &Path) -> anyhow::Result<()> {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
state.failed_versions.push(OfficialFailedVersionRecord {
|
||||
upsert_failed_version(
|
||||
&mut state.failed_versions,
|
||||
version,
|
||||
error: "上一次官方资源同步在完成发布前中断".to_string(),
|
||||
failed_unix_seconds: unix_seconds_now(),
|
||||
});
|
||||
"上一次官方资源同步在完成发布前中断",
|
||||
unix_seconds_now(),
|
||||
);
|
||||
trim_failed_versions(&mut state.failed_versions);
|
||||
state.updated_unix_seconds = unix_seconds_now();
|
||||
write_version_state(path, &state)
|
||||
@@ -2047,6 +2048,9 @@ fn complete_version_state(
|
||||
completed_unix_seconds: Some(unix_seconds_now()),
|
||||
..record
|
||||
});
|
||||
if let Some(current) = state.current_completed_version.as_ref() {
|
||||
remove_completed_version_failures(&mut state.failed_versions, current);
|
||||
}
|
||||
state.in_progress_version = None;
|
||||
state.updated_unix_seconds = unix_seconds_now();
|
||||
write_version_state(path, &state)
|
||||
@@ -2059,11 +2063,12 @@ fn fail_version_state(
|
||||
) -> anyhow::Result<()> {
|
||||
let mut state = read_version_state(path)?.unwrap_or_default();
|
||||
state.in_progress_version = None;
|
||||
state.failed_versions.push(OfficialFailedVersionRecord {
|
||||
version: record,
|
||||
error: error.to_string(),
|
||||
failed_unix_seconds: unix_seconds_now(),
|
||||
});
|
||||
upsert_failed_version(
|
||||
&mut state.failed_versions,
|
||||
record,
|
||||
error,
|
||||
unix_seconds_now(),
|
||||
);
|
||||
trim_failed_versions(&mut state.failed_versions);
|
||||
state.updated_unix_seconds = unix_seconds_now();
|
||||
write_version_state(path, &state)
|
||||
@@ -2121,6 +2126,37 @@ fn trim_failed_versions(failed_versions: &mut Vec<OfficialFailedVersionRecord>)
|
||||
}
|
||||
}
|
||||
|
||||
fn upsert_failed_version(
|
||||
failed_versions: &mut Vec<OfficialFailedVersionRecord>,
|
||||
record: OfficialVersionRecord,
|
||||
error: &str,
|
||||
failed_unix_seconds: u64,
|
||||
) {
|
||||
if let Some(index) = failed_versions.iter().position(|failed| {
|
||||
failed_version_matches(&failed.version, &record) && failed.error == error
|
||||
}) {
|
||||
failed_versions.remove(index);
|
||||
}
|
||||
failed_versions.push(OfficialFailedVersionRecord {
|
||||
version: record,
|
||||
error: error.to_string(),
|
||||
failed_unix_seconds,
|
||||
});
|
||||
}
|
||||
|
||||
fn remove_completed_version_failures(
|
||||
failed_versions: &mut Vec<OfficialFailedVersionRecord>,
|
||||
completed: &OfficialVersionRecord,
|
||||
) {
|
||||
failed_versions.retain(|failed| !failed_version_matches(&failed.version, completed));
|
||||
}
|
||||
|
||||
fn failed_version_matches(left: &OfficialVersionRecord, right: &OfficialVersionRecord) -> bool {
|
||||
left.app_version == right.app_version
|
||||
&& left.bundle_version == right.bundle_version
|
||||
&& left.addressables_root == right.addressables_root
|
||||
}
|
||||
|
||||
fn snapshot_path_for_state_path(
|
||||
_snapshot: &OfficialUpdateSnapshot,
|
||||
resource_root: &Path,
|
||||
@@ -2764,6 +2800,76 @@ mod tests {
|
||||
assert!(state.failed_versions[0].error.contains("403"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_state_deduplicates_repeated_failures_and_clears_after_success() {
|
||||
let temp = tempfile::TempDir::new().unwrap();
|
||||
let path = temp.path().join("official-version-state.json");
|
||||
let snapshot = OfficialUpdateSnapshot::new(
|
||||
fixture_base_snapshot(),
|
||||
vec![fixture_marker("current")],
|
||||
Some(&fixture_bootstrap()),
|
||||
);
|
||||
let active = temp.path().join("versions/active");
|
||||
|
||||
for id in ["broken-1", "broken-2"] {
|
||||
let staging = temp.path().join(".staging").join(id);
|
||||
let failed = prepare_in_progress_version_state(
|
||||
&path,
|
||||
&snapshot,
|
||||
id,
|
||||
&active,
|
||||
None,
|
||||
&staging,
|
||||
&staging.join("official-sync-snapshot.json"),
|
||||
)
|
||||
.unwrap();
|
||||
fail_version_state(&path, failed, "download 403").unwrap();
|
||||
}
|
||||
|
||||
let state = read_version_state(&path).unwrap().unwrap();
|
||||
assert_eq!(state.failed_versions.len(), 1);
|
||||
assert_eq!(state.failed_versions[0].version.id, "broken-2");
|
||||
assert_eq!(state.failed_versions[0].error, "download 403");
|
||||
|
||||
let staging = temp.path().join(".staging/broken-3");
|
||||
let failed = prepare_in_progress_version_state(
|
||||
&path,
|
||||
&snapshot,
|
||||
"broken-3",
|
||||
&active,
|
||||
None,
|
||||
&staging,
|
||||
&staging.join("official-sync-snapshot.json"),
|
||||
)
|
||||
.unwrap();
|
||||
fail_version_state(&path, failed, "download 404").unwrap();
|
||||
let state = read_version_state(&path).unwrap().unwrap();
|
||||
assert_eq!(state.failed_versions.len(), 2);
|
||||
|
||||
let staging = temp.path().join(".staging/fixed");
|
||||
let fixed = prepare_in_progress_version_state(
|
||||
&path,
|
||||
&snapshot,
|
||||
"fixed",
|
||||
&active,
|
||||
None,
|
||||
&staging,
|
||||
&staging.join("official-sync-snapshot.json"),
|
||||
)
|
||||
.unwrap();
|
||||
let published = temp.path().join("versions/fixed");
|
||||
complete_version_state(
|
||||
&path,
|
||||
fixed,
|
||||
&published,
|
||||
&published.join("official-sync-snapshot.json"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let state = read_version_state(&path).unwrap().unwrap();
|
||||
assert!(state.failed_versions.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_rejects_dangerous_output_root_before_network_work() {
|
||||
let config = OfficialUpdateConfig {
|
||||
|
||||
Reference in New Issue
Block a user