Merge pull request #263 from appergb/fix/local-asr-pr-review-fixes
fix(local-asr): 修 PR #262 review 提的两个 bug
This commit is contained in:
1 file changed
+22
-7
@@ -384,7 +384,11 @@ async fn run_download(
|
||||
}));
|
||||
}
|
||||
|
||||
// 区分"用户主动取消" vs "我们因为某个 worker 失败了主动 abort 其它 worker":
|
||||
// 都共用同一个 cancel AtomicBool(worker 端只看一个 flag 就够),但外层用
|
||||
// `self_aborted` 记是哪种情况,决定最后 emit Cancelled 还是 Failed。
|
||||
let mut first_err: Option<anyhow::Error> = None;
|
||||
let mut self_aborted = false;
|
||||
while let Some(joined) = futs.next().await {
|
||||
match joined {
|
||||
Ok(Ok(())) => {}
|
||||
@@ -392,9 +396,12 @@ async fn run_download(
|
||||
if first_err.is_none() {
|
||||
first_err = Some(e);
|
||||
}
|
||||
// 取消其它正在跑的:cancel flag 设为 true,让所有 spawn task 早退
|
||||
// 一个 worker 失败 → 让其它 worker 立即停,免得它们继续吃带宽
|
||||
// 然后用户还得等到所有任务完成才看到失败。
|
||||
if !cancel.load(Ordering::SeqCst) {
|
||||
log::warn!("[local-asr] one file failed; signaling others to stop");
|
||||
log::warn!("[local-asr] one file failed; aborting other workers");
|
||||
cancel.store(true, Ordering::SeqCst);
|
||||
self_aborted = true;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -405,7 +412,8 @@ async fn run_download(
|
||||
}
|
||||
}
|
||||
|
||||
if cancel.load(Ordering::SeqCst) {
|
||||
// 用户主动 cancel(不是我们因为错误自己 set 的)→ Cancelled
|
||||
if cancel.load(Ordering::SeqCst) && !self_aborted {
|
||||
emit_cancelled(app, model_id, "", 0, file_count, total_bytes);
|
||||
return Ok(());
|
||||
}
|
||||
@@ -684,17 +692,24 @@ async fn try_download_range_append(
|
||||
if status.as_u16() != 200 && status.as_u16() != 206 {
|
||||
anyhow::bail!("HTTP {status} for {url}");
|
||||
}
|
||||
if status.as_u16() == 200 && range_start > 0 {
|
||||
let _ = std::fs::remove_file(partial);
|
||||
}
|
||||
let effective_start = if status.as_u16() == 200 { 0 } else { range_start };
|
||||
|
||||
// 截断 partial 到本次 attempt 的起点,再 seek 写入。
|
||||
// 老 append 实现的 bug:若上一次 attempt 已写了部分字节后失败,retry 拿到的还是
|
||||
// 完整 chunk → append → 文件比应有大小多 N 字节 → 永久损坏。
|
||||
// 小文件路径每个 chunk 是整个文件(≤ 32MB),用 truncate 重写最直白。
|
||||
let mut file = tokio::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.write(true)
|
||||
.open(partial)
|
||||
.await
|
||||
.with_context(|| format!("open partial failed: {}", partial.display()))?;
|
||||
file.set_len(effective_start)
|
||||
.await
|
||||
.with_context(|| format!("truncate partial failed: {}", partial.display()))?;
|
||||
file.seek(std::io::SeekFrom::Start(effective_start))
|
||||
.await
|
||||
.with_context(|| format!("seek partial failed: {}", partial.display()))?;
|
||||
|
||||
let mut stream = resp.bytes_stream();
|
||||
let mut written: u64 = 0;
|
||||
|
||||
Reference in new issue
Block a user