Conversation
`ASAP_THANOS_QUERY_URL` was the only switch that built a `ThanosQueryEngine`, and nothing in the repo set it — no compose file, CI config or script — so the forwarder never ran and the archive slot always held `NoDataArchiveEngine`. Delete the engine rather than leave ~1.2k lines reachable only from its own tests: the `thanos_query_engine/` module, its re-exports, the four mock-Thanos tests in `http.rs`, and the startup wiring in `main.rs`. `ASAP_REQUIRE_ARCHIVE_ENGINE` goes too — with no real archive engine it only chose between an empty result and a 503. The archive slot keeps the `NoDataArchiveEngine` stub for now; it is removed later in this series along with the archive routing itself. Scoping decisions for the series: .design_docs/REMOVE_THANOS_FORWARDER_DECISIONS.md Refs #746 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
With the Thanos forwarder gone the archive slot could only ever hold an empty-result stub, so every archive routing decision produced an empty-but-successful answer that masked the warm tier. Collapse the policy table to its one remaining branch — `PrometheusRemote` answers from Prometheus, every ASAP-managed axis from the sketch tier — and drop the machinery that existed to pick between warm and archive: * `RangeTier` and the `execute_range_for_tier*` variants, plus `classify_range_tier`'s warm-retention split in the HTTP layer * the `AccuracyTarget` argument threaded through the router, now that no engine answers "exactly" * the two `resolve_metric_storage` overrides (topk with no heap-bearing sid, `sum_over_time` over counter deltas) and their helpers — both existed to push a query the sketch tier cannot serve onto the archive A query the ASAP tier cannot serve now forwards to the Prometheus fallback, which is a real answer where the archive returned an empty one. `X-ASAP-Accuracy: exact` keeps its meaning by taking the same route: skip the sketches, ask Prometheus. Both query paths honour it. `NoEngineRegistered` stays a fail-loud 503 — no engine for the metric's tier is a deploy misconfig, not a capability miss. Refs #746 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`build_routing_entry` gave every metric a second target claiming the shapes no sketch can answer — `histogram_quantile`, `delta`, `deriv`, `absent`, `rate_post_hoc`, plus `topk` without a CountSketch and `count` without an HLL/CMS. The data plane no longer has an engine for that slot, so pointing at it would only name a tier that isn't there. Emit the `asap_query` default slot alone. The claimed shapes now miss on the ASAP tier and reach the backend's Prometheus fallback — the same destination, minus the pretend hop. `asap_tier_native_shapes` stays: it is informational and useful on its own. This lands before the backend drops the `thanos_query` engine id so no commit in the series emits plans the backend would reject. Refs #746 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nothing routes to the archive slot any more, so its occupants are dead code: `NoDataArchiveEngine` (which existed only to answer cold queries with an empty result instead of a 503) and `with_archive_query_engine`, which was identical to `with_query_engine`. The ASAP engine's hybrid warm+archive stitch goes too. Production never wired it — `with_archive_engine` was `#[cfg(test)]` and only one test called it — so `archive_engine`, `stitch_warm_and_archive` and their tests described a merge that never ran. A partial-coverage range query keeps failing closed with a CapabilityMiss, which the HTTP layer now forwards to Prometheus. Refs #746 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The archive tier is gone, so its wire vocabulary is too: `StorageBackend::GorillaObjectStore`, `ENGINE_ID_THANOS_QUERY`, and the `thanos_query` entry in `CANONICAL_QUERY_ENGINE_IDS`. A routing plan still naming `thanos_query` is now rejected the way any unknown engine is, rather than resolving to a tier that cannot answer. There are no production deployments to roll forward, and the control plane stopped emitting that target in the previous commit, so nothing in-tree emits a plan the backend would refuse. Tests that used the archive axis as "some non-sketch backend" now use `DoubleWrite`, which is what they were really testing; the engine-override tests target `double_write` for the same reason. Refs #746 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`fallback/metrics.rs` declared `queryengine_hot_queries_total`, `queryengine_cold_queries_total` and `queryengine_cold_bytes_served_total` and never incremented any of them — no call site, no dashboard, no scrape config. A hot-vs-cold split has nothing left to measure now that there is one tier, so the module goes. The rest is comments that still told readers a capability miss "falls through to Thanos archive" — the most misleading thing left in the tree after this series. They now describe the Prometheus fallback. `GORILLA_MERGER_DESIGN.md` gets the status it earned: the write path in `gorilla-merger/` still exists, its backend read path does not, and the doc names the commit to restore the engine from if the direction is revived. Refs #746 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The decisions log was scaffolding for scoping this removal, not something the codebase needs to carry. It lives in the PR description instead, where reviewers read it. Earlier commit messages in this series still point at the file; the PR body is the copy that survives. Refs #746 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
zzylol
deleted the
746-remove-asap_thanos_query_url-and-the-thanos-archive-forwarder
branch
September 21, 2026 18:39
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.
Closes #746.
ASAP_THANOS_QUERY_URLwas the only switch that built aThanosQueryEngine, and nothing in the repo set it — no compose file, CI config or script. The forwarder never ran; the archive slot always heldNoDataArchiveEngine, which answers instant queries with an empty-but-successful result. So every archive routing decision quietly returned "no data" where the Prometheus fallback would have returned a real answer.Removing just the flag would have stranded ~1.2k lines reachable only from their own tests, so this removes the archive tier from the query path: 20 files, +668 / −2967.
Scoping Q&A
当前决策层级
--forward-unsupported-queriesthanos_query;删除归档引擎、存储类型和占位引擎NoEngineRegistered现在都返回 503Scoped by interview before any code was written. Each question, the evidence behind it, and the answer:
Q1. Delete
ThanosQueryEngineentirely, or only the env-var wiring?Outside the env wiring, the engine was built only by 4 tests in
http.rs;thanos_query_engine/forward.rswas ~1.2k lines. Removing only the env var would have left it as dead code.→ Delete entirely: the module, its re-exports, the 4 mock-Thanos tests, the
main.rsregistration, and the doc comments pointing at it.Q2. Keep the
"thanos_query"engine ID? (superseded by Q10/Q11)The ID was a wire contract, not just an engine name: the control plane emitted it in routing plans,
StorageBackend::GorillaObjectStoremapped to and from it,NoDataArchiveEngineregistered under it, clients selected it viaX-ASAP-Engine/?engine=, and ~10 HTTP tests asserteddata_source: thanos_query.→ Originally "keep it", then reversed once the archive routing itself went (Q10/Q11).
Q3. Keep or remove
ASAP_REQUIRE_ARCHIVE_ENGINE?With Thanos gone it only chose between the empty-result stub and no engine (503
NoEngineRegistered). Nothing in the repo set it.→ Remove it. Re-examined once more when it turned out the flag interacts with the Prometheus fallback:
Ok(empty)fromNoDataArchiveEngine::execute, so the fallback was never reached.process_via_routerhad no fallback call even onNoEngineRegistered, so the flag didn't route those to Prometheus either.execute_range(trait default =CapabilityMiss), so range misses already reached the Prometheus fallback.Decision unchanged; nothing set it, so no behaviour changed.
Q4. The Gorilla merger's read path depends on
ThanosQueryEngine. Proceed?gorilla-merger/(Go) andGORILLA_MERGER_DESIGN.mdplanned for cold reads to go backend →ThanosQueryEngine→ thanos-query → merger StoreAPI + S3. The design's own cleanup step said "setASAP_THANOS_QUERY_URL".→ Proceed; that direction is shelved. The design doc now records that its backend read path is removed and names the commit to restore the engine from.
Q5. Keep or remove the archive routing itself?
With only the stub in the slot,
Exact→ archive-only, ASAPCapabilityMiss→ archive failover and the warm-retention range split all produced empty results that looked successful. The surface: the policy table,RangeTier+execute_range*tier variants,classify_range_tier, theX-ASAP-Accuracyheader, the tworesolve_metric_storageoverrides, the ASAP engine's never-wired warm/archive stitch, the never-incremented cold counters, the control plane'sthanos_querytarget, and ~40 tests — ~2–2.5k lines, ~70% tests.→ Remove it.
Q6. What serves a query the ASAP tier can't answer, once there's no archive?
→ The Prometheus fallback when
--prometheus-serveris configured, otherwise the adapter's unsupported-query response. This is what the approximateSketchStoreinstant path already did and what range misses effectively did. Today's silent empty instant results become real answers.Q7. What does
X-ASAP-Accuracy: exactmean now?Its only effect was routing:
Exactskipped the sketch tier for the archive. (AccuracyTarget::Exactelsewhere — ClickHouse accelerator, control-plane planner — is unrelated and stays.)→ Keep the header;
exactnow means "skip the sketch tier, go straight to Prometheus". Preserves the caller contract, keeps validation and the 400 on typos.Q8. Should the control plane stop emitting
thanos_querytargets?build_routing_entrygave every metric anasap_querydefault plus athanos_querytarget claiminghistogram_quantile,delta,deriv,absent,rate_post_hoc, plustopk(no CountSketch) andcount(no HLL/CMS).→ Stop emitting it. Those shapes now miss on the ASAP tier and go to Prometheus — same destination, minus the pretend hop.
asap_tier_native_shapesstays; it's informational.Q9. What about the two archive overrides in
resolve_metric_storage?Both existed so a query the sketch tier can't answer would reach the router instead of dying on the direct sketch path:
topkwith no heap-bearing sid, andsum_over_timeover counter deltas (#301, whereExactAgg(Sum)sids can't reconstruct Σ-of-cumulative-samples). They were workarounds for the direct path having no fallback — exactly what Q6 now provides.→ Delete both and their helpers.⚠️ #301's fix now depends on
--prometheus-server; see below.Q10. Delete
NoDataArchiveEngine, and what aboutGorillaObjectStore/"thanos_query"?→ Delete the stub,
with_archive_query_engineand themain.rsblock — and remove theStorageBackend::GorillaObjectStorevariant,ENGINE_ID_THANOS_QUERYand itsCANONICAL_QUERY_ENGINE_IDSentry. Supersedes Q2.Q11. How should the backend treat a
thanos_querytarget in an incoming plan?parse_engine_stringerrors on unknown engines, and that error rejects the whole routing document — so a control plane still emitting the target would have its plans refused.→ Hard-reject, same as any unknown engine. No legacy-skip path: there are no production deployments, so deploy order isn't a concern.
Q12. How does this land?
→ One PR, commits in dependency order, each building and passing tests on its own.
Q13. Which e2e suites gate this?
→ The full
data_plane/testssuite, not just the two in the blast radius.Commits
Review commit by commit; each is independently green.
8f829f6ddelete the Thanos forwarder + both env vars (Q1, Q3, Q4)3d3e3223remove data-plane archive routing — policy table,RangeTier, accuracy header, the two overrides (Q5, Q6, Q7, Q9)8f666c01control plane stops emitting archive targets (Q8)f2ab3105remove the archive engine slot: stub + the ASAP engine's never-wired warm/archive stitch (Q10)197b816edrop theGorillaObjectStoreaxis andthanos_queryid (Q10, Q11)2e433dcfdelete dead cold counters, refresh stale comments + the merger design doc3f23ef42drop the scoping-decisions file (it lives in this description)Two deviations from the plan above: Q7's accuracy change landed inside commit 2 rather than getting a commit that only moved a line; and Q8 moved earlier than Q12 had it, ahead of the id removal — otherwise an intermediate commit would emit plans its own backend rejects.
Behaviour changes worth a close look
--prometheus-server.sum_over_timeover counter deltas andtopkwith no heap-bearing sid used to be pushed to the archive for an exact answer. They now miss on the ASAP tier and forward to Prometheus — a real answer where the archive gave an empty one, but "unsupported query" instead of an empty result when no fallback is configured.gorilla-merger/'s read path is gone. Its write path still exists and still ships blocks to S3; nothing in the backend can query them.NoEngineRegisteredstays a fail-loud 503. No engine for a metric's tier is a deploy misconfig, not a capability miss, so it isn't quietly forwarded.Verification
cargo test --workspace --lib: 1153 data_plane + 422 control_plane + 108 asap_types, all passing.cargo test -p data_plane --tests: full e2e suite green, includinge2e_controller_plans_and_backend_serves(13 tests) covering the control-plane→backend plan wire this series changes.cargo fmt+cargo clippyclean — every commit went through the repo's pre-commit hooks.backend_process_e2e's single test is#[ignore]d on main for an unrelated ASAPCollector schema dependency, so it contributed no coverage here.🤖 Generated with Claude Code