Skip to content

refactor(query): remove ASAP_THANOS_QUERY_URL and the archive tier - #750

Merged
zzylol merged 9 commits into
mainfrom
746-remove-asap_thanos_query_url-and-the-thanos-archive-forwarder
Sep 21, 2026
Merged

zzylol merged 9 commits into
mainfrom
746-remove-asap_thanos_query_url-and-the-thanos-archive-forwarder

Conversation

@milindsrivastava1997

@milindsrivastava1997 milindsrivastava1997 commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Closes #746.

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. The forwarder never ran; the archive slot always held NoDataArchiveEngine, 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

当前决策层级

层级 核心决定 对应问题 当前状态
1. 目标 停用 Thanos 和 Gorilla merger 的归档路径 Q1、Q4、Q5 两者的代码和入口均已删除
2. 查询行为 ASAP 无法处理时,按入口回退到 Prometheus、VictoriaMetrics 或 ClickHouse Q6、Q7、Q9 三个入口分别实现;PromQL 回退仍需启用 --forward-unsupported-queries
3. 路由契约 不再生成或接受 thanos_query;删除归档引擎、存储类型和占位引擎 Q2、Q3、Q8、Q10、Q11 已实现;即时和范围查询的 NoEngineRegistered 现在都返回 503
4. 交付验证 按依赖顺序提交,运行相应测试 Q12、Q13 PR 现有 9 个提交;描述中的提交列表和验证数字仍停留在较早版本

Scoped by interview before any code was written. Each question, the evidence behind it, and the answer:

Q1. Delete ThanosQueryEngine entirely, 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.rs was ~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.rs registration, 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::GorillaObjectStore mapped to and from it, NoDataArchiveEngine registered under it, clients selected it via X-ASAP-Engine / ?engine=, and ~10 HTTP tests asserted data_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:

  • Instant queries: router-dispatched queries got Ok(empty) from NoDataArchiveEngine::execute, so the fallback was never reached. process_via_router had no fallback call even on NoEngineRegistered, so the flag didn't route those to Prometheus either.
  • Range queries: the stub never implemented 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) and GORILLA_MERGER_DESIGN.md planned for cold reads to go backend → ThanosQueryEngine → thanos-query → merger StoreAPI + S3. The design's own cleanup step said "set ASAP_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, ASAP CapabilityMiss → 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, the X-ASAP-Accuracy header, the two resolve_metric_storage overrides, the ASAP engine's never-wired warm/archive stitch, the never-incremented cold counters, the control plane's thanos_query target, 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-server is configured, otherwise the adapter's unsupported-query response. This is what the approximate SketchStore instant path already did and what range misses effectively did. Today's silent empty instant results become real answers.

Q7. What does X-ASAP-Accuracy: exact mean now?

Its only effect was routing: Exact skipped the sketch tier for the archive. (AccuracyTarget::Exact elsewhere — ClickHouse accelerator, control-plane planner — is unrelated and stays.)

→ Keep the header; exact now 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_query targets?

build_routing_entry gave every metric an asap_query default plus a thanos_query target claiming histogram_quantile, delta, deriv, absent, rate_post_hoc, plus topk (no CountSketch) and count (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_shapes stays; 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: topk with no heap-bearing sid, and sum_over_time over counter deltas (#301, where ExactAgg(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 about GorillaObjectStore / "thanos_query"?

→ Delete the stub, with_archive_query_engine and the main.rs block — and remove the StorageBackend::GorillaObjectStore variant, ENGINE_ID_THANOS_QUERY and its CANONICAL_QUERY_ENGINE_IDS entry. Supersedes Q2.

Q11. How should the backend treat a thanos_query target in an incoming plan?

parse_engine_string errors 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/tests suite, not just the two in the blast radius.


Commits

Review commit by commit; each is independently green.

  1. 8f829f6d delete the Thanos forwarder + both env vars (Q1, Q3, Q4)
  2. 3d3e3223 remove data-plane archive routing — policy table, RangeTier, accuracy header, the two overrides (Q5, Q6, Q7, Q9)
  3. 8f666c01 control plane stops emitting archive targets (Q8)
  4. f2ab3105 remove the archive engine slot: stub + the ASAP engine's never-wired warm/archive stitch (Q10)
  5. 197b816e drop the GorillaObjectStore axis and thanos_query id (Q10, Q11)
  6. 2e433dcf delete dead cold counters, refresh stale comments + the merger design doc
  7. 3f23ef42 drop 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

  • Issue asap engine: ExactAgg(Sum) dispatch collapses sum/sum_over_time/increase/rate to same code path (function semantics lost) #301's fix now depends on --prometheus-server. sum_over_time over counter deltas and topk with 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.
  • NoEngineRegistered stays 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, including e2e_controller_plans_and_backend_serves (13 tests) covering the control-plane→backend plan wire this series changes.
  • cargo fmt + cargo clippy clean — every commit went through the repo's pre-commit hooks.
  • Note: 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

`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
zzylol merged commit 7604d6f into main Sep 21, 2026
1 check passed
@zzylol
zzylol deleted the 746-remove-asap_thanos_query_url-and-the-thanos-archive-forwarder branch September 21, 2026 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove ASAP_THANOS_QUERY_URL and the Thanos archive forwarder

2 participants