mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-09-29 00:12:12 +00:00
perf(send): write the fallback temp file on a blocking thread
download_to_temp wrote the whole buffered body — up to MAX_MEDIA_UPLOAD_BYTES, 50 MiB — with a sync write_all on whatever executor thread ran the prep task; six PREP slots could stall six runtime threads at once on a slow volume (Docker volume, SD card), pausing unrelated handlers and chat-action refreshes with them. The write now runs in spawn_blocking, the pattern the photo decode in the same file already uses; the failure classes are unchanged (write error = retryable resource exhaustion, panic = permanent, worker bugs must be loud).
This commit is contained in:
@@ -123,14 +123,25 @@ async fn download_to_temp(
|
|||||||
.map_err(|e| FallbackError::Permanent {
|
.map_err(|e| FallbackError::Permanent {
|
||||||
message: format!("temp file failed: {e}"),
|
message: format!("temp file failed: {e}"),
|
||||||
})?;
|
})?;
|
||||||
use std::io::Write;
|
// The write runs on a blocking thread: up to 50 MiB of sync disk I/O on
|
||||||
// A write failure is resource exhaustion far more often than a broken temp
|
// an executor thread would stall whatever else that worker runs (six prep
|
||||||
|
// tasks could stall six threads at once on a slow volume). A write
|
||||||
|
// failure is resource exhaustion far more often than a broken temp
|
||||||
// dir (ENOSPC / EDQUOT), and that clears on its own — worth an attempt
|
// dir (ENOSPC / EDQUOT), and that clears on its own — worth an attempt
|
||||||
// instead of dropping the post on the first try. Creating the file (above)
|
// instead of dropping the post on the first try. Creating the file (above)
|
||||||
// stays permanent: a temp dir that cannot be created at all is a
|
// stays permanent: a temp dir that cannot be created at all is a
|
||||||
// deployment fault that should fail loudly and immediately. `Retryable`
|
// deployment fault that should fail loudly and immediately. `Retryable`
|
||||||
// carries no message, so the cause is logged here.
|
// carries no message, so the cause is logged here.
|
||||||
file.as_file_mut().write_all(&bytes).map_err(|e| {
|
let (written, file, bytes) = tokio::task::spawn_blocking(move || {
|
||||||
|
use std::io::Write;
|
||||||
|
let written = file.as_file_mut().write_all(&bytes);
|
||||||
|
(written, file, bytes)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(|e| FallbackError::Permanent {
|
||||||
|
message: format!("upload write worker panicked: {e}"),
|
||||||
|
})?;
|
||||||
|
written.map_err(|e| {
|
||||||
log::error!("temp file write failed: {e}");
|
log::error!("temp file write failed: {e}");
|
||||||
FallbackError::Retryable {
|
FallbackError::Retryable {
|
||||||
delay_seconds: retry_delay_seconds(0),
|
delay_seconds: retry_delay_seconds(0),
|
||||||
|
|||||||
Reference in New Issue
Block a user