mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-08 05:20:59 +03:00
fix(file-transfer): improve large directory loading (#15830)
* fix(file-transfer): improve large directory loading Signed-off-by: fufesou <linlong1266@gmail.com> * fix(file-transfer): avoid failing newer directory reads Track each remote directory request by its registered completer and only remove the task when it still matches, preventing stale failures from affecting newer requests for the same path. Signed-off-by: fufesou <linlong1266@gmail.com> * fix(file-transfer): handle slow directory listings safely Signed-off-by: fufesou <linlong1266@gmail.com> * fix(file transfer): correlate directory responses with requests Signed-off-by: fufesou <linlong1266@gmail.com> * fix(file transfer): prevent automatic directory responses from matching requests Signed-off-by: fufesou <linlong1266@gmail.com> * fix(file-transfer): handle large remote directory listings reliably - build file rows lazily - register remote reads before sending requests - handle Home paths, stale responses, errors, and timeouts - serialize same-path reads with different hidden-file options Signed-off-by: fufesou <linlong1266@gmail.com> * fix(file transfer): reduce diffs Signed-off-by: fufesou <linlong1266@gmail.com> * fix: build Signed-off-by: fufesou <linlong1266@gmail.com> * fix: invalidate pending dir reads on reconnect Signed-off-by: fufesou <linlong1266@gmail.com> * test(file-transfer): cover remote directory read lifecycle Signed-off-by: fufesou <linlong1266@gmail.com> --------- Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -1546,13 +1546,19 @@ async fn read_dir(dir: &str, include_hidden: bool, tx: &UnboundedSender<Data>) {
|
||||
fs::get_path(dir)
|
||||
}
|
||||
};
|
||||
if let Ok(Ok(fd)) = spawn_blocking(move || fs::read_dir(&path, include_hidden)).await {
|
||||
let mut msg_out = Message::new();
|
||||
let mut file_response = FileResponse::new();
|
||||
file_response.set_dir(fd);
|
||||
msg_out.set_file_response(file_response);
|
||||
send_raw(msg_out, tx);
|
||||
}
|
||||
let result = spawn_blocking(move || fs::read_dir(&path, include_hidden)).await;
|
||||
let msg_out = match result {
|
||||
Ok(Ok(fd)) => {
|
||||
let mut msg_out = Message::new();
|
||||
let mut file_response = FileResponse::new();
|
||||
file_response.set_dir(fd);
|
||||
msg_out.set_file_response(file_response);
|
||||
msg_out
|
||||
}
|
||||
Ok(Err(err)) => fs::new_error(0, err, -1),
|
||||
Err(err) => fs::new_error(0, err, -1),
|
||||
};
|
||||
send_raw(msg_out, tx);
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "ios")))]
|
||||
@@ -1750,7 +1756,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
#[cfg(not(any(target_os = "ios")))]
|
||||
fn read_dir_success() {
|
||||
fn read_dir_reports_success_and_error() {
|
||||
let rt = Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let (tx, mut rx) = unbounded_channel();
|
||||
@@ -1773,6 +1779,18 @@ mod tests {
|
||||
_ => panic!("unexpected data"),
|
||||
}
|
||||
let _ = fs::remove_dir_all(&dir);
|
||||
|
||||
super::read_dir(&dir.to_string_lossy(), false, &tx).await;
|
||||
|
||||
match rx.recv().await.unwrap() {
|
||||
Data::RawMessage(bytes) => {
|
||||
let mut msg = Message::new();
|
||||
msg.merge_from_bytes(&bytes).unwrap();
|
||||
assert_eq!(msg.file_response().error().id, 0);
|
||||
assert!(!msg.file_response().error().error.is_empty());
|
||||
}
|
||||
_ => panic!("unexpected data"),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user