Conversation
try_run_sql wraps the query in tokio::time::timeout(state.timeout) but prepares the statement first, outside it. When an attempt times out, dropping the query future does not stop the statement on the server, and tokio-postgres serializes statements on a connection, so the next attempt's prepare waits behind the stuck statement with no deadline. Release-qualification 1373, "Checks 0dt upgrade to a bumped version": the SELECT over alter_index_source in AlterIndex.validate() timed out after the 300 s platform-checks budget at 23:41 UTC, and the job then produced nothing until Buildkite cancelled it at 02:51. The retry loop is bounded by max_duration(state.timeout); the prepare it called was not (QAR-167). Wrap the prepare in the same timeout, so a connection held by a stuck statement fails the attempt within the budget and the failure is reported against the query rather than as a silent step timeout. The message names the phase so the two timeouts are distinguishable in a log. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
bosconi
marked this pull request as ready for review
September 17, 2026 20:12
bosconi
enabled auto-merge (squash)
September 17, 2026 20:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
QAR-167. On release-qualification#1373,
Checks 0dt upgrade to a bumped versionranSELECT ... FROM alter_index_sourceinAlterIndex.validate(), hit the 300 s platform-checks budget (query timed out) at 23:41 UTC, printed onerows didn't match; sleeping to see if dataflow catches upline, and then produced nothing at all until Buildkite cancelled the step at 02:51.The retry loop in
run_sqlis bounded bymax_duration(state.timeout), so it was not the loop. Intry_run_sql, onlyquery_prepared(...)is insidetokio::time::timeout(state.timeout, ...); thepgclient.prepare(query)before it is not. Dropping a timed-out query future does not stop the statement on the server, and tokio-postgres serializes statements on one connection, so the retry'spreparewaits behind the stuck statement for as long as the server keeps it. On a dataflow that never produces, that is until the step is killed.Description
Wrap the prepare in the same timeout. A connection held by a stuck statement now fails the attempt within the budget, the retry loop runs out of
max_durationand reports the failure against the query, and the step ends in minutes instead of hours. The timeout message names the phase (preparing query timed out) so it is distinguishable fromquery timed outin a log.This does not cancel the stuck statement server-side; testdrive only does that for background queries (
cancel_background_query). With platform-checks'statement_timeout='300s'the server ends it on its own, and for other compositions the bounded failure is still the right outcome: the underlying problem, a query that never returns, is what the test should report.Why the underlying
alter_index_sourcequery never returned afterZeroDowntimeBumpedVersionis the product half of QAR-167 and is not addressed here.Verification
cargo checkandcargo clippy -p mz-testdrive -D warningsclean. No unit-test seam exists fortry_run_sql(it drives a live pgwire client); the behavior change is a deadline on an existing await, and every testdrive-based CI job exercises the happy path.🤖 Generated with Claude Code