3 Commits
Author SHA1 Message Date
clawbot 822f03193a Say govips gives pixa no way to stop an encode; give AVIF's worst case
check / check (push) Canceled after 0s
libvips can stop a running encode, but govips gives pixa no way to ask
it to, which README.md "Routes" and the Process and encode comments
now say in place of "libvips cannot stop an encode". The avifEffort
comment gives its 51 seconds as the RGB time and 110 seconds with an
alpha channel as the worst case, as README.md does.

Model: opus-5-5
2026-10-15 12:07:12 +00:00
clawbot d5052495c7 Answer 503 to a request waiting on a transcode stopped at a deadline
check / check (push) Canceled after 0s
A request that waited for another request's transcode got that
request's deadline error when the transcode stopped at its deadline,
and both image routes answered it 500, though the waiting request's
own downstream_timeout had time left. The image service now returns
ErrProcessingTimedOut for it, which both routes answer 503 "server
busy, try again later", as when pixa is busy. README.md "Routes" says
so.

Model: opus-5-5
2026-10-15 12:06:38 +00:00
clawbot 6572b3fe08 Test the 503 for a request waiting on a transcode stopped at a deadline
check / check (push) Canceled after 0s
A request that waited for another request's transcode, stopped at that
request's deadline, must get ErrProcessingTimedOut, which both image
routes answer 503. Declares that error so the tests build. Also tests
that Process, past its deadline before it starts, never reads its input.

Model: opus-5-5
2026-10-15 12:03:53 +00:00
+12 -13
View File
@@ -49,39 +49,38 @@ func TestServerBusyAnswers503(t *testing.T) {
}
}
// TestProcessingTimedOutAnswers503 checks that respondImageError and
// handleImageError, which answer the errors of the two image routes, answer
// 503 with the server busy error when the image service reports that
// processing stopped at the deadline of the request doing it, wrapped as the
// service wraps it. A request that waited for that processing gets this error
// while its own deadline may have time left. The request's source only goes
// into a log line, so it is left empty.
// TestProcessingTimedOutAnswers503 checks that both image routes answer 503
// with the server busy error when the image service reports that processing
// stopped at the deadline of the request doing it, wrapped as the service
// wraps it. A request that waited for that processing gets this error while
// its own deadline may have time left.
func TestProcessingTimedOutAnswers503(t *testing.T) {
t.Parallel()
h := &Handlers{log: slog.New(slog.DiscardHandler)}
req := &imgcache.ImageRequest{SourceHost: "img.example.com", SourcePath: "/a.jpg"}
err := fmt.Errorf("%w: failed to encode: %w",
imgcache.ErrProcessingTimedOut, context.DeadlineExceeded)
plain := httptest.NewRecorder()
h.respondImageError(plain, &imgcache.ImageRequest{}, err)
h.respondImageError(plain, req, err)
encrypted := httptest.NewRecorder()
h.handleImageError(encrypted, err)
for name, rec := range map[string]*httptest.ResponseRecorder{
"respondImageError": plain, "handleImageError": encrypted,
for route, rec := range map[string]*httptest.ResponseRecorder{
"/v1/image/": plain, "/v1/e/": encrypted,
} {
t.Logf("%s: status = %d, body = %q", name, rec.Code, rec.Body.String())
t.Logf("%s: status = %d, body = %q", route, rec.Code, rec.Body.String())
if rec.Code != http.StatusServiceUnavailable {
t.Errorf("%s: status = %d, want %d",
name, rec.Code, http.StatusServiceUnavailable)
route, rec.Code, http.StatusServiceUnavailable)
}
if !strings.Contains(rec.Body.String(), "server busy, try again later") {
t.Errorf("%s: body = %q, want the server busy error",
name, rec.Body.String())
route, rec.Body.String())
}
}
}