mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-07-22 08:26:44 +08:00
fix: harden official resource sync retries
This commit is contained in:
@@ -329,6 +329,21 @@ impl OfficialResourcePullService {
|
||||
return Err(format!("Refusing to fetch non-official URL: {url}"));
|
||||
}
|
||||
|
||||
let attempts = self.retry_attempts.max(1);
|
||||
let mut last_error = None;
|
||||
for attempt in 1..=attempts {
|
||||
match self.fetch_bytes_once(url) {
|
||||
Ok(bytes) => return Ok(bytes),
|
||||
Err(error) => {
|
||||
last_error = Some(format!("attempt {attempt}/{attempts}: {error}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(last_error.unwrap_or_else(|| format!("curl failed for {url} without an attempt")))
|
||||
}
|
||||
|
||||
fn fetch_bytes_once(&self, url: &str) -> Result<Vec<u8>, String> {
|
||||
let output = Command::new(&self.curl_command)
|
||||
.arg("--fail")
|
||||
.arg("--location")
|
||||
@@ -1078,7 +1093,7 @@ mod tests {
|
||||
fn inventory() -> YostarJpDownloadInventory {
|
||||
YostarJpDownloadInventory::from_catalog_bytes(
|
||||
b"FullPatch_000.zip",
|
||||
b"ExcelDB.db",
|
||||
b"ExcelDB.db ExcelDB.db",
|
||||
b"JP_Airi.zip",
|
||||
)
|
||||
}
|
||||
@@ -1680,6 +1695,31 @@ fi
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn retries_transient_fetch_bytes_failures() {
|
||||
let out_dir = TempDir::new().unwrap();
|
||||
let bin_dir = TempDir::new().unwrap();
|
||||
let curl_path = bin_dir.path().join("curl");
|
||||
write_fake_flaky_curl(&curl_path);
|
||||
|
||||
let service = OfficialResourcePullService::with_curl_command(out_dir.path(), &curl_path)
|
||||
.with_retry_attempts(2);
|
||||
let bytes = service
|
||||
.fetch_bytes(
|
||||
"https://prod-clientpatch.bluearchiveyostar.com/r93_token/TableBundles/TableCatalog.bytes",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
String::from_utf8(bytes).unwrap(),
|
||||
"https://prod-clientpatch.bluearchiveyostar.com/r93_token/TableBundles/TableCatalog.bytes"
|
||||
);
|
||||
assert_eq!(
|
||||
fs::read_to_string(curl_path.with_extension("state")).unwrap(),
|
||||
"2"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_non_official_urls() {
|
||||
let service = OfficialResourcePullService::new("/tmp/unused");
|
||||
|
||||
Reference in New Issue
Block a user