* refactor: remove datanode and meta-srv dep from frontend Signed-off-by: shuiyisong <xixing.sys@gmail.com> * refactor: use on-device protoc if possible Signed-off-by: shuiyisong <xixing.sys@gmail.com> * refactor: remove unused dep Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: CR issue Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: version and docs Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: update logs Co-authored-by: fys <40801205+fengys1996@users.noreply.github.com> --------- Signed-off-by: shuiyisong <xixing.sys@gmail.com> Co-authored-by: fys <40801205+fengys1996@users.noreply.github.com>
3.9 KiB
frontend — Agent & Contributor Guide
Navigation aid for src/frontend. Keep it short and point to code. Paths are
relative to the repo root.
Repo-wide rules that apply here: .agents/architecture-invariants.md.
What this crate does
Frontend is the request entry point and orchestration layer. It accepts
multi-protocol requests (gRPC, HTTP, MySQL, PostgreSQL, InfluxDB, OTLP, Jaeger,
Prometheus, OpenTSDB), checks permissions, parses/plans SQL, and dispatches:
reads go to the query engine (query crate), writes go to the inserter/deleter
(operator crate).
Boundary with servers: the servers crate implements the wire protocols and
network I/O; frontend provides the business logic by implementing handler
traits (SqlQueryHandler, GrpcQueryHandler, InfluxdbLineProtocolHandler,
...). In standalone mode the standalone crate bridges the frontend to an
embedded datanode RegionServer; in distributed mode the frontend talks to
remote datanodes via operator/client.
Module map
| Module | Path | Purpose |
|---|---|---|
instance |
src/frontend/src/instance.rs |
Instance: the core handler; implements SqlQueryHandler, PrometheusHandler, etc. |
instance/builder |
src/frontend/src/instance/builder.rs |
FrontendBuilder assembles Instance from its dependencies |
instance/grpc |
src/frontend/src/instance/grpc.rs |
GrpcQueryHandler: insert/delete/query/promql over gRPC |
instance/region_query |
src/frontend/src/instance/region_query.rs |
Routes distributed region reads to datanodes |
instance/* |
src/frontend/src/instance/ |
Per-protocol handlers (influxdb.rs, promql.rs, otlp/, jaeger.rs, logs.rs, prom_store.rs, ...) |
frontend |
src/frontend/src/frontend.rs |
Frontend lifecycle wrapper (FrontendOptions, start/shutdown) |
server |
src/frontend/src/server.rs |
Services: builds and wires the protocol servers |
heartbeat |
src/frontend/src/heartbeat.rs |
Heartbeat to metasrv; handles suspend / cache invalidation |
service_config |
src/frontend/src/service_config/ |
Per-protocol option structs |
Request lifecycles
- SQL query (
instance.rs):do_query_innerhandles parsing, interceptors, permission checks, timeout/cancellation, and delegates planning/execution toStatementExecutor. Distributed scans enter throughregion_query.rs. - Insert (
instance/grpc.rs):handle_inserts/handle_row_inserts→check_permission→operator'sInserter(schema validation, optional auto-create, partition routing) → localRegionServer(standalone) or RPC to datanodes (distributed).
Public surface
Instance(instance.rs) — the business-logic container.Frontend(frontend.rs) — lifecycle wrapper aroundInstance+ servers + heartbeat.- Created from
cmd:src/cmd/src/frontend.rs(distributed) andsrc/cmd/src/standalone.rs(standalone, with embedded datanode).
When you change X, also touch Y
servershandler traits: a new/changed protocol handler requires the matchingimplhere.operatorInserter/Deleter orqueryQueryEngine API: update the call sites ininstance.rs/instance/grpc.rs.session::QueryContext: new context fields thread through most handlers.sqlstatements: new statement kinds need handling inquery_statement.
Testing
cargo nextest run -p frontend
Gotchas
- Keep the frontend/servers split straight: wire format and network live in
servers; permissions, planning, and routing live here. - Standalone vs distributed diverge in datanode access (the
standalonecrate's localRegionServeradapter vsNodeClientsRPC), MetaClient usage, and whether heartbeat matters. In standalone, the cache invalidator is a no-op.
Maintenance contract
Update this file when you add a protocol handler, change the query/insert
lifecycle, or change how Instance is constructed or wired to servers.