fix(uploads): bound the silence in an upload body with a re-armed read deadline
A body that stopped arriving held one of the receive slots (#47) and a spool file indefinitely. Every read of the upload body now pushes the connection read deadline UploadIdleTimeout (default 60 s) ahead, so a stalled body fails its read, Accept returns and the slot is released, while a slow but moving body is never cut (ReadTimeout would cut it). Two things found by running it over a socket: - metrics.statusWriter had no Unwrap, so http.ResponseController could not reach the connection and the bound silently did not apply in the production handler stack. It now unwraps; a writer that still cannot set a deadline logs "upload idle bound unavailable". - clearing the deadline on any read error left net/http's pre-reply drain of the unread remainder unbounded, so the connection hung. The deadline is now cleared only on a clean io.EOF. ADR-033 limitation amended. A 1-byte-per-59-s drip is still unbounded. Closes #56 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -116,6 +116,11 @@ type App struct {
|
||||
// front rather than discovered by failing.
|
||||
Uploads Uploader
|
||||
UploadLimits uploads.Limits
|
||||
// UploadIdleTimeout is how long an upload body may go without delivering a byte
|
||||
// before the connection read is cut off and its receive slot freed (#56). Zero
|
||||
// means defaultUploadIdleTimeout. It bounds silence, not the whole body, so a
|
||||
// large upload on a slow but moving link still completes.
|
||||
UploadIdleTimeout time.Duration
|
||||
// UploadChatMaxChars is the transcript budget for chat over an uploaded
|
||||
// recording. The caption default (18,000 chars, ~22 minutes of speech) would
|
||||
// keep only the first third of an hour-long meeting.
|
||||
|
||||
Reference in New Issue
Block a user