perf: offload MD5 checksum to spawn_blocking in chunked uploads
md5::compute(&data) is CPU-bound (~1.2ms per 5MB chunk) and was blocking the Tokio worker thread. Move it to the blocking thread-pool via spawn_blocking so the async worker is freed in ~5µs. Bytes::clone is O(1) (Arc increment) so no extra copy overhead.
This commit is contained in:
@@ -499,10 +499,18 @@ impl ChunkedUploadService {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify checksum if provided
|
// Verify checksum if provided — MD5 is CPU-bound (~1.2 ms per 5 MB),
|
||||||
|
// so we offload it to the blocking thread-pool to keep the Tokio
|
||||||
|
// worker free for other connections.
|
||||||
if let Some(ref expected_checksum) = checksum {
|
if let Some(ref expected_checksum) = checksum {
|
||||||
let actual_checksum = format!("{:x}", md5::compute(&data));
|
let data_clone = data.clone(); // Bytes::clone is O(1) — just an Arc increment
|
||||||
if &actual_checksum != expected_checksum {
|
let actual_checksum = tokio::task::spawn_blocking(move || {
|
||||||
|
format!("{:x}", md5::compute(&data_clone))
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("MD5 checksum task failed: {e}"))?;
|
||||||
|
|
||||||
|
if actual_checksum != *expected_checksum {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Checksum mismatch: expected {}, got {}",
|
"Checksum mismatch: expected {}, got {}",
|
||||||
expected_checksum, actual_checksum
|
expected_checksum, actual_checksum
|
||||||
|
|||||||
Reference in New Issue
Block a user