Skip to content

fix(http): consult per-metric BackendStorageRouting on every query (issue #46 ⑤) - #89

Merged
zzylol merged 1 commit into
mainfrom
mvp/http-router-engine-dispatch
May 6, 2026
Merged

zzylol merged 1 commit into
mainfrom
mvp/http-router-engine-dispatch

Conversation

@zzylol

@zzylol zzylol commented May 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes the issue-46 v2 criterion ⑤ partial-pass: data_source: gorilla_archive never landed on cold-archive responses because the HTTP query handler bypassed EngineRouter for every query.

Root cause (per the v2 root-cause analysis on issue #46): the Phase-5 dispatch read the per-metric StorageBackend from StreamingConfig::storage_backend() — a single field. The deployed precompute_engine binary loads the streaming config via StreamingConfig::from_yaml_file → from_yaml_data, which constructs via Self::new(...) and always defaults the axis to SketchWarmTier. So the EngineRouter was effectively never consulted in production.

Per the user's architecture correction: the streaming engine never sees Gorilla data on its OTLP-ingest path (the agent's gorillas3processor writes chunks directly to S3), so there is nothing for StreamingConfig::from_yaml_data to learn. The fix lives in a separate per-metric routing layer.

What changed

  • New BackendStorageRouting data type — a {metric_name: StorageBackend} map loaded from YAML at startup. Schema:
    default: sketch_warm_tier
    metrics:
      http_requests_total: gorilla_s3_archive
  • New --backend-storage-routing CLI flag (alias ASAP_BACKEND_STORAGE_ROUTING env var) on both the precompute_engine binary (used by the deployed Docker image) and the legacy query_engine_rust binary.
  • HttpServer::with_backend_storage_routing(...) wires the routing table into AppState.
  • process_query_request now consults the routing table on every PromQL query: parses the query, extracts the first metric name from the AST via promql_parser, looks up the storage backend, and dispatches through EngineRouter for any per-metric override. Falls back to the streaming-config single axis when no routing table is wired (preserves pre-Phase-5 behaviour).

Test plan

  • 6 new BackendStorageRouting unit tests (empty router, YAML round-trip, defaults).
  • 3 new end-to-end production-path unit tests in http.rs::tests:
    • http_production_path_routes_archive_metric_via_routing_table — streaming-config stays default (SketchWarmTier); routing table flips http_requests_totalgorilla_s3_archive; the response carries data_source: gorilla_archive and the mock GorillaQueryEngine is hit exactly once.
    • http_production_path_unlisted_metric_falls_back_to_warm_tier — non-listed metric still hits SimpleEngine direct path.
    • http_production_path_default_axis_routes_all_metricsdefault: gorilla_s3_archive (no per-metric overrides) routes everything.
  • All 5 pre-existing http-router tests still pass (http_routes_archive_metric_to_gorilla_engine, etc.).
  • cargo test -p query_engine_rust --lib drivers::query::servers::http: 25 tests pass.
  • cargo build -p query_engine_rust --bins: clean.

🤖 Generated with Claude Code

The Phase-5/6 EngineRouter wiring (PR #87) sourced the per-metric
StorageBackend axis from `StreamingConfig::storage_backend()` — a
single field that applies to the entire streaming config. In production
deploys the YAML loader (`StreamingConfig::from_yaml_data`) constructs
via `Self::new(...)` and always defaults `storage_backend` to
`SketchWarmTier`, so the HTTP handler always took the
`SimpleEngine`-direct-dispatch branch and the EngineRouter was
effectively bypassed for every query — `data_source: gorilla_archive`
never landed on cold-archive responses (issue #46 v2 criterion 5
PARTIAL).

Per the design correction: the streaming engine never sees Gorilla
data on its OTLP-ingest path (the agent's `gorillas3processor` writes
chunks directly to S3), so there is nothing for
`StreamingConfig::from_yaml_data` to learn. The fix lives in a
separate per-metric routing layer:

- New `BackendStorageRouting` data type (`{metric_name: StorageBackend}`
  map) loaded once at startup from `--backend-storage-routing` YAML
  (or its `ASAP_BACKEND_STORAGE_ROUTING` env-var alias). Wired on both
  the legacy `query_engine_rust` binary and the deployed
  `precompute_engine` binary so the Docker image picks it up.
- HTTP handler's `process_query_request` extracts the metric name
  from the PromQL AST (via `promql_parser`) and consults the routing
  table; falls back to the streaming-config single axis only when no
  routing table is wired (preserves pre-Phase-5 behaviour).
- Three new unit tests exercise the **production code path** (routing
  table loaded, streaming-config default unchanged) — distinct from
  the existing tests that mock the dispatch by pinning
  `streaming_cfg.storage_backend` directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zzylol
zzylol merged commit 1a912dc into main May 6, 2026
@zzylol
zzylol deleted the mvp/http-router-engine-dispatch branch May 9, 2026 18:00
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.

1 participant