Merge pull request #2467 from Kingtous/master
fix: infinite loop when skipping files
This commit is contained in:
commit
f5f8226f5d
@ -572,6 +572,22 @@ impl TransferJob {
|
|||||||
self.file_skipped() && self.files.len() == 1
|
self.file_skipped() && self.files.len() == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether the job is completed after `read` returns `None`
|
||||||
|
/// This is a helper function which gives additional lifecycle when the job reads `None`.
|
||||||
|
/// If returns `true`, it means we can delete the job automatically. `False` otherwise.
|
||||||
|
///
|
||||||
|
/// [`Note`]
|
||||||
|
/// Conditions:
|
||||||
|
/// 1. Files are not waiting for comfirmation by peers.
|
||||||
|
#[inline]
|
||||||
|
pub fn job_completed(&self) -> bool {
|
||||||
|
// has no error, Condition 2
|
||||||
|
if !self.enable_overwrite_detection || (!self.file_confirmed && !self.file_is_waiting) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get job error message, useful for getting status when job had finished
|
/// Get job error message, useful for getting status when job had finished
|
||||||
pub fn job_error(&self) -> Option<String> {
|
pub fn job_error(&self) -> Option<String> {
|
||||||
if self.job_skipped() {
|
if self.job_skipped() {
|
||||||
@ -597,7 +613,6 @@ impl TransferJob {
|
|||||||
match r.union {
|
match r.union {
|
||||||
Some(file_transfer_send_confirm_request::Union::Skip(s)) => {
|
Some(file_transfer_send_confirm_request::Union::Skip(s)) => {
|
||||||
if s {
|
if s {
|
||||||
log::debug!("skip file id:{}, file_num:{}", r.id, r.file_num);
|
|
||||||
self.set_file_skipped();
|
self.set_file_skipped();
|
||||||
} else {
|
} else {
|
||||||
self.set_file_confirmed(true);
|
self.set_file_confirmed(true);
|
||||||
@ -744,13 +759,16 @@ pub async fn handle_read_jobs(
|
|||||||
stream.send(&new_block(block)).await?;
|
stream.send(&new_block(block)).await?;
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
if !job.enable_overwrite_detection || (!job.file_confirmed && !job.file_is_waiting)
|
if job.job_completed() {
|
||||||
{
|
finished.push(job.id());
|
||||||
// for getting error detail, we do not remove this job, we will handle it in io loop
|
let err = job.job_error();
|
||||||
if job.job_error().is_none() {
|
if err.is_some() {
|
||||||
finished.push(job.id());
|
stream
|
||||||
|
.send(&new_error(job.id(), err.unwrap(), job.file_num()))
|
||||||
|
.await?;
|
||||||
|
} else {
|
||||||
|
stream.send(&new_done(job.id(), job.file_num())).await?;
|
||||||
}
|
}
|
||||||
stream.send(&new_done(job.id(), job.file_num())).await?;
|
|
||||||
} else {
|
} else {
|
||||||
// waiting confirmation.
|
// waiting confirmation.
|
||||||
}
|
}
|
||||||
|
@ -933,14 +933,12 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
err = job.job_error();
|
err = job.job_error();
|
||||||
fs::remove_job(d.id, &mut self.write_jobs);
|
fs::remove_job(d.id, &mut self.write_jobs);
|
||||||
}
|
}
|
||||||
if let Some(job) = fs::get_job(d.id, &mut self.read_jobs) {
|
|
||||||
job.modify_time();
|
|
||||||
err = job.job_error();
|
|
||||||
fs::remove_job(d.id, &mut self.read_jobs);
|
|
||||||
}
|
|
||||||
self.handle_job_status(d.id, d.file_num, err);
|
self.handle_job_status(d.id, d.file_num, err);
|
||||||
}
|
}
|
||||||
Some(file_response::Union::Error(e)) => {
|
Some(file_response::Union::Error(e)) => {
|
||||||
|
if let Some(job) = fs::get_job(e.id, &mut self.write_jobs) {
|
||||||
|
fs::remove_job(e.id, &mut self.write_jobs);
|
||||||
|
}
|
||||||
self.handle_job_status(e.id, e.file_num, Some(e.error));
|
self.handle_job_status(e.id, e.file_num, Some(e.error));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -75,6 +75,11 @@ pub enum FS {
|
|||||||
id: i32,
|
id: i32,
|
||||||
file_num: i32,
|
file_num: i32,
|
||||||
},
|
},
|
||||||
|
WriteError {
|
||||||
|
id: i32,
|
||||||
|
file_num: i32,
|
||||||
|
err: String
|
||||||
|
},
|
||||||
WriteOffset {
|
WriteOffset {
|
||||||
id: i32,
|
id: i32,
|
||||||
file_num: i32,
|
file_num: i32,
|
||||||
|
@ -1304,6 +1304,13 @@ impl Connection {
|
|||||||
last_modified: d.last_modified,
|
last_modified: d.last_modified,
|
||||||
is_upload: true,
|
is_upload: true,
|
||||||
}),
|
}),
|
||||||
|
Some(file_response::Union::Error(e)) => {
|
||||||
|
self.send_fs(ipc::FS::WriteError {
|
||||||
|
id: e.id,
|
||||||
|
file_num: e.file_num,
|
||||||
|
err: e.error,
|
||||||
|
});
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Some(message::Union::Misc(misc)) => match misc.union {
|
Some(message::Union::Misc(misc)) => match misc.union {
|
||||||
|
@ -596,6 +596,12 @@ async fn handle_fs(fs: ipc::FS, write_jobs: &mut Vec<fs::TransferJob>, tx: &Unbo
|
|||||||
fs::remove_job(id, write_jobs);
|
fs::remove_job(id, write_jobs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ipc::FS::WriteError { id, file_num, err } => {
|
||||||
|
if let Some(job) = fs::get_job(id, write_jobs) {
|
||||||
|
send_raw(fs::new_error(job.id(), err, file_num), tx);
|
||||||
|
fs::remove_job(job.id(), write_jobs);
|
||||||
|
}
|
||||||
|
}
|
||||||
ipc::FS::WriteBlock {
|
ipc::FS::WriteBlock {
|
||||||
id,
|
id,
|
||||||
file_num,
|
file_num,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user