mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 11:56:23 +08:00
fix(release): 收紧分发热路径与事务边界
This commit is contained in:
@@ -13,6 +13,7 @@ use crate::official_changes::{
|
||||
write_official_resource_change_handoff, OfficialResourceChangeHandoffReport,
|
||||
OfficialResourceChangeSummary,
|
||||
};
|
||||
use crate::official_download::OFFICIAL_CAS_REUSE_REFERENCES_FILE;
|
||||
use crate::official_game_main_config::{
|
||||
resolve_game_main_config_source, OfficialGameMainConfigSelectedSource,
|
||||
OfficialGameMainConfigSourceKind,
|
||||
@@ -1128,7 +1129,20 @@ impl OfficialPublishLayout {
|
||||
if !path_exists_no_follow(active_root)? {
|
||||
return Ok(());
|
||||
}
|
||||
copy_tree_no_symlink(active_root, staging_root, active_root == self.root)
|
||||
copy_tree_no_symlink(active_root, staging_root, active_root == self.root)?;
|
||||
if active_root != self.root {
|
||||
let cas_references = staging_root.join(OFFICIAL_CAS_REUSE_REFERENCES_FILE);
|
||||
if path_exists_no_follow(&cas_references)? {
|
||||
ensure_safe_file_target(staging_root, &cas_references, "staging CAS 引用清单")?;
|
||||
fs::remove_file(&cas_references).map_err(|error| {
|
||||
format!(
|
||||
"清理 active release CAS ownership 清单失败 {}:{error}",
|
||||
cas_references.display()
|
||||
)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn legacy_manifest_exists(&self) -> Result<bool, String> {
|
||||
@@ -4309,21 +4323,22 @@ fn required_platform(endpoint: &YostarJpResourceEndpoint) -> anyhow::Result<Patc
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct OfficialUpdateLock {
|
||||
pub(crate) struct OfficialUpdateLock {
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
impl OfficialUpdateLock {
|
||||
fn acquire(config: &OfficialUpdateConfig) -> anyhow::Result<Self> {
|
||||
validate_output_root(&config.output_root).map_err(anyhow::Error::msg)?;
|
||||
ensure_safe_directory_path(&config.output_root, "资源输出目录")
|
||||
.map_err(anyhow::Error::msg)?;
|
||||
fs::create_dir_all(&config.output_root)?;
|
||||
ensure_safe_directory_path(&config.output_root, "资源输出目录")
|
||||
.map_err(anyhow::Error::msg)?;
|
||||
let path = config.lock_path();
|
||||
ensure_safe_file_target(&config.output_root, &path, "官方同步锁")
|
||||
.map_err(anyhow::Error::msg)?;
|
||||
Self::acquire_output_root(&config.output_root)
|
||||
}
|
||||
|
||||
pub(crate) fn acquire_output_root(output_root: &Path) -> anyhow::Result<Self> {
|
||||
validate_output_root(output_root).map_err(anyhow::Error::msg)?;
|
||||
ensure_safe_directory_path(output_root, "资源输出目录").map_err(anyhow::Error::msg)?;
|
||||
fs::create_dir_all(output_root)?;
|
||||
ensure_safe_directory_path(output_root, "资源输出目录").map_err(anyhow::Error::msg)?;
|
||||
let path = output_root.join(".official-sync.lock");
|
||||
ensure_safe_file_target(output_root, &path, "官方同步锁").map_err(anyhow::Error::msg)?;
|
||||
for attempt in 0..=1 {
|
||||
let mut options = OpenOptions::new();
|
||||
options.write(true).create_new(true);
|
||||
@@ -4361,6 +4376,12 @@ impl OfficialUpdateLock {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn acquire_official_output_lock(
|
||||
output_root: &Path,
|
||||
) -> anyhow::Result<OfficialUpdateLock> {
|
||||
OfficialUpdateLock::acquire_output_root(output_root)
|
||||
}
|
||||
|
||||
impl Drop for OfficialUpdateLock {
|
||||
fn drop(&mut self) {
|
||||
let expected = std::process::id().to_string();
|
||||
|
||||
Reference in New Issue
Block a user