[bug][Upload][v2] The callback function progressHandler in the upload method sometimes works, sometimes it doesn't.
The callback function progressHandler in the upload method sometimes works, sometimes it doesn't. The download method is not a problem. The progressHandler function in the upload method does not trigger after being triggered a few times.
My file is around 30 megabytes, and the progressHandler triggered these a few times:
[✔] Environment - OS: Windows 10.0.22631 X64 ✔ WebView2: 118.0.2088.76 ✔ MSVC: Visual Studio Community 2022 ✔ rustc: 1.78.0 (9b00956e5 2024-04-29) ✔ cargo: 1.78.0 (54d8815d0 2024-03-26) ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24) ✔ Rust toolchain: stable-x86_64-pc-windows-msvc (default) - node: 20.12.2 - yarn: 1.22.22 - npm: 10.5.0
[-] Packages - tauri [RUST]: 2.0.0-beta.22 - tauri-build [RUST]: 2.0.0-beta.17 - wry [RUST]: 0.40.1 - tao [RUST]: 0.28.0 - @tauri-apps/api [NPM]: 2.0.0-beta.13 - @tauri-apps/cli [NPM]: 2.0.0-beta.18
[-] App - build-type: bundle - CSP: unset - frontendDist: ../dist - devUrl: http://localhost:1420/ - framework: React - bundler: Vite
Would you happen to be able to provide a minimal reproduction example? It seems to work fine on my end so it may be implementation specific (doesn't rule out a bug in the plugin)
@FabianLars I found that the backend has fully received the files from the frontend and the request is complete. But the front-end progress has only been printed a few times. This number of times is uncertain, depending on when the request is completed. Moreover, this issue is particularly evident when uploading the same file here for the second time. Here is an example: https://github.com/DWHengr/upload-demo
Actually now that i think about it, i talked to someone on Discord about a similar problem where the ipc::Channel kept losing events just like this. I can't find the convos anymore thore, but maybe @lucasfernog remembers something (i know that i pinged you for it but idk what happened after lol)
Is there any solution. I am unable to display the progress of file upload correctly at the moment.
I've encountered the same issue. Could it be caused by the high frequency of these messages? I'm not sure if adding a debounce might solve the problem.
#[command]
async fn download(
url: &str,
file_path: &str,
headers: HashMap<String, String>,
on_progress: Channel<ProgressPayload>,
) -> Result<()> {
let client = reqwest::Client::new();
let mut request = client.get(url);
// Loop trought the headers keys and values
// and add them to the request object.
for (key, value) in headers {
request = request.header(&key, value);
}
let response = request.send().await?;
let total = response.content_length().unwrap_or(0);
let mut file = BufWriter::new(File::create(file_path).await?);
let mut stream = response.bytes_stream();
let mut last_progress = 0u64;
let mut last_send_time = Instant::now();
let debounce_duration = std::time::Duration::from_millis(200);
while let Some(chunk) = stream.try_next().await? {
file.write_all(&chunk).await?;
last_progress = last_progress + chunk.len() as u64;
if last_send_time.elapsed() >= debounce_duration || last_progress == total {
let _ = on_progress.send(ProgressPayload {
progress: last_progress,
total,
});
last_send_time = Instant::now();
}
}
file.flush().await?;
Ok(())
}
You can try this code
#[command] async fn download( url: &str, file_path: &str, headers: HashMap<String, String>, on_progress: Channel<ProgressPayload>, ) -> Result<()> { let client = reqwest::Client::new(); let mut request = client.get(url); // Loop trought the headers keys and values // and add them to the request object. for (key, value) in headers { request = request.header(&key, value); } let response = request.send().await?; let total = response.content_length().unwrap_or(0); let mut file = BufWriter::new(File::create(file_path).await?); let mut stream = response.bytes_stream(); let mut last_progress = 0u64; let mut last_send_time = Instant::now(); let debounce_duration = std::time::Duration::from_millis(200); while let Some(chunk) = stream.try_next().await? { file.write_all(&chunk).await?; last_progress = last_progress + chunk.len() as u64; if last_send_time.elapsed() >= debounce_duration || last_progress == total { let _ = on_progress.send(ProgressPayload { progress: last_progress, total, }); last_send_time = Instant::now(); } } file.flush().await?; Ok(()) }你可以尝试这个代码 I think this code is what people expected. Have you considered modifying it into the upload plugin
@BaLaLaLs Thank you for your reply. I'm not an expert in Rust and Tauri, so I'm not sure if this is a better solution (I personally think it might be an issue with Tauri 2.0's messaging mechanism, as high-frequency messages could cause message deadlocks, but other APIs' transformCallback work normally, meaning I haven't yet identified the essence of the problem). Additionally, this code was modified based on suggestions from GPT, so I recommend using it as a reference for now.
I wanted to add on to this conversation that the callback pretty regularly fails when the file is sufficiently large. The file I am testing with is over 2GB and it consistently hits this error JS side
But the file downloads without issue, just the IPC seems to break. Additionally, it seems that after I get this error I am unable to do any further downloads until I restart the app -- I need to test if it breaks all IPC or just the download chain