serve: add --requestTimeout and --warmupRevision controls#415
Merged
Conversation
Two operability controls for the `serve` query service: - --requestTimeout <seconds>: bounds how long an /impacted_targets(_with_distances) request may run before the server abandons it and returns 504. The JDK HttpServer's maxReqTime/maxRspTime system properties can't do this — they only cover reading the request and writing the response, not the bazel query that runs inside the handler. So the timeout is enforced in-handler: when set, the query runs on a bounded worker and the handler waits with future.get(timeout). 0 (default) keeps the original unbounded behavior. Health checks are unaffected. - --warmupRevision <revs>: comma-separated git revisions whose hashes are generated and cached at startup, before the server reports healthy, so the first real request is warm and the Bazel analysis server is primed. Readiness-gated (the load balancer won't route until warm) and best-effort (a revision that fails to warm is logged and the server still becomes ready, serving it cold on demand) so a bad --warmupRevision can't lame-duck a deploy. Tests cover the 504 timeout path, warmup coverage/best-effort, and that a failed warmup still becomes ready. README regenerated for the two new flags. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Overview
Adds two operability controls to the
bazel-diff servequery service (issue #29):--requestTimeout <seconds>— bounds how long a request may run.--warmupRevision <revs>— primes the hash cache + Bazel server at startup.--requestTimeoutBounds how long an
/impacted_targets//impacted_targets_with_distancesrequest may run before the server abandons it and returns504.0(the default) means no timeout, preserving current behavior.Why in-handler rather than a JVM property: the JDK
HttpServer'ssun.net.httpserver.maxReqTime/maxRspTimeonly bound reading the request (instant for a GET) and writing the response — neither covers thebazel querythat runs synchronously inside the handler, which is the slow part. So they can't ever interrupt a slow query. The timeout is therefore enforced in the handler: when set, the query runs on a bounded worker executor and the handler waits withfuture.get(timeout), mappingTimeoutException→504.future.cancel(true)interrupts the handler thread, but the underlyingbazel querysubprocess may not honor the interrupt and can keep running in the background. That's fine — it frees the client immediately and the query still populates the per-SHA cache, so a retry is fast.--warmupRevisionComma-separated git revisions (branch/tag/SHA) whose hashes are generated and cached at startup, before the server reports healthy, so the first real request is warm and the Bazel analysis server is primed (the cold first
bazel queryis the expensive one).ready.set(true), so a load balancer won't route to the instance until it's hydrated.--warmupRevisioncan't lame-duck a deploy. (Deliberately different from fetch failure, which does lame-duck, because a broken clone can't serve correct answers.)--no-initial-fetch(resolving against the local clone) for local/offline priming.Note for reviewers: warmup makes
servedo real Bazel work at startup, increasing time-to-healthy. Deploy/health-check timeouts should be sized accordingly (called out in the flag help text).Tests
BazelDiffServerTest.slowRequestTimesOutWith504— a provider that blocks past a 1s budget returns504.ServeCommandTest.warmUpCacheGeneratesEachRevisionAndIsBestEffort— each revision is warmed; a failing one neither throws nor stops the others.ServeCommandTest.warmupFailureStillBecomesReady— health is200even when warmup fails.All serve tests pass (
//cli:ServeCommandTest,//cli:BazelDiffServerTest). README regenerated viabazel run //tools:generate-readme(only the serve help block changed).Follow-ups (not in this PR)
tools/serve_harness.pycase that startsserve --warmupRevision <sha>against the real fixture repo and asserts the first request logs a cache hit.ImpactedTargetsService→HashService).🤖 Generated with Claude Code