Skip to content

Always signal S3 upload completion so failed uploads don't hang the handler - #72

Merged
jtomson merged 1 commit into
masterfrom
fix-s3-upload-hang
Nov 3, 2026
Merged

jtomson merged 1 commit into
masterfrom
fix-s3-upload-hang

Conversation

@jtomson

@jtomson jtomson commented Oct 30, 2026 •

Copy link
Copy Markdown

What this does

uploadToS3 only sent on the uploaded channel when PutObject succeeded. If the session or the upload failed it returned without sending, and the processing handler waited on <-uploaded forever after it had already written the image to the client.

Each stuck handler keeps its processing semaphore token (released by a defer at processing_handler.go:302) and its queue token, so every failed upload permanently takes one of the IMGPROXY_WORKERS slots. With the default of GOMAXPROCS x 2, a handful of S3 errors (expired credentials, throttling, an outage) leaves the instance unable to render anything until it restarts. Cached images still serve from S3/CloudFront, so it shows up as new renders stalling.

The send now happens in a defer with the upload result, and the channel is buffered so the goroutine can't block either.

How I tested it

Added TestBeforeResponseSignalsOnUploadFailure, which forces PutObject to fail validation locally (empty bucket, no network) and waits up to 10s for the channel.
Before the fix it fails at the 10s timeout. After the fix it passes, and go test . passes.

🤖 Generated with Claude Code

@jtomson
jtomson marked this pull request as ready for review November 3, 2026 19:59
…andler

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jtomson
jtomson force-pushed the fix-s3-upload-hang branch from 7b22a38 to 33881e6 Compare November 3, 2026 20:02
@jtomson
jtomson merged commit d3578a6 into master Nov 3, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant