fix(query): apply queryTimeout to queryMeasurement endpoint - #701
fix(query): apply queryTimeout to queryMeasurement endpoint#701MrBeldum wants to merge 3 commits into
Conversation
GET /api/v1/query/:measurement used context.Background() and Query() without a deadline, so configured queryTimeout never applied. Wrap UserContext with queryTimeout matching the POST /api/v1/query sibling. Fixes Basekick-Labs#308
|
All contributors have signed the CLA. Thanks! |
xe-nvdk
left a comment
There was a problem hiding this comment.
Thanks for taking #308. This is the right fix, and it verified out at every level I tested. Two administrative items block the merge, listed at the end.
What I verified:
Cancel ownership. The contract with executeArrowJSONQuery holds exactly as your comment states: every handled=true path releases the cancel func (immediate error paths directly, the success path inside the stream callback), and the handled=false driver-fallback path returns without cancelling, so the database/sql fallback receives a live context. On the fallback itself, every return path after the context is created releases cancel: the QueryContext error, the Columns error, and the stream writer callback. The ColumnTypes error deliberately falls through, so nothing leaks there either.
Pattern match. The wiring matches the established handlers: UserContext as the base so client disconnects propagate, ctx.Err() == context.DeadlineExceeded for the 504 classification, cancel called in the stream callback rather than deferred because SetBodyStreamWriter runs after the handler returns.
Tests. Full internal/api suite green under -race, with and without -tags=duckdb_arrow. TestQueryMeasurementAppliesQueryTimeout fails against the pre-fix handler, so the regression is pinned.
Live server. I ran the confirmation your test plan left unchecked. With query.timeout = 1 on a duckdb_arrow build, an expensive where subquery against GET /api/v1/query/cpu returned 504 "Query timed out" at 1.5s and bumped arc_query_timeouts_total from 0 to 1, through the Arrow path. The same query on a pre-fix build from main ran 9.5 seconds past the configured timeout and returned 200 with the counter untouched. Fast queries still return 200 in single-digit milliseconds under the timeout-aware code.
One optional note on the second test: TestQueryMeasurementNoTimeoutKeepsUserContext also passes against the pre-fix handler, because a nil-deadline context cannot be told apart from context.Background(). If you want it to pin UserContext propagation, inject a marked context in middleware (app.Use(func(c *fiber.Ctx) error { c.SetUserContext(ctxWithTestValue); return c.Next() })) and assert the value comes through. Fine to skip.
Blocking for merge, both quick:
- CLA. The CLA check is failing; signing is required on every PR. Please sign per the bot's instructions in this thread and comment
recheck. - Release notes. Community fixes get an entry in the current planned release file. Please add a short entry near the top of the Bug fixes section in
RELEASE_NOTES_2026.09.2.mddescribing the fix, ending with the standard credit line you can copy from any neighboring entry.
|
@MrBeldum thank you for this fix — the review verified it end to end, including a live 504 A/B against a pre-fix build, and it is ready to merge from our side. To move it along I have covered the release-notes item from my review myself: your branch now carries the 26.09.2 entry with your credit line, plus a merge with current main so everything is up to date. The only remaining step is yours: please sign the CLA per the bot's instructions in this thread and comment |
|
I have read the CLA Document and I hereby sign the CLA |
|
recheck |
Summary
GET /api/v1/query/:measurementexecuted againstcontext.Background()anddb.Query()with no deadline, so configuredqueryTimeoutnever applied (high(query): queryMeasurement endpoint has no timeout #308).c.UserContext()withqueryTimeout(same pattern asPOST /api/v1/query), pass the cancel func into the Arrow dispatch, and useQueryContexton the database/sql fallback."Query timed out"and increments timeout metrics. Stream and error paths cancel the context.Fixes #308
Test plan
go test -tags=duckdb_arrow ./internal/api/(full package, including newTestQueryMeasurementAppliesQueryTimeout)query_timeoutactually 504s a slowGET /api/v1/query/:measurementin a running server (verified in review: 504 at 1.5s with query.timeout=1, timeout metric incremented; pre-fix build ran 9.5s past the timeout)