* docs(agents): add per-crate guides, architecture invariants, and generated-files list Add agent/contributor navigation docs modeled on the AGENTS.md convention: - Per-crate AGENTS.md for hot crates (mito2, metric-engine, flow, frontend, meta-srv): module map, read/write paths, change-coupling points, test commands, and gotchas. - .agents/architecture-invariants.md: repo-wide rules that clippy and the style guide do not cover (format compatibility, crate layering, async runtimes, error handling, experimental gating, the DataFusion fork). - .agents/generated-files.md: tool-generated artifacts that must not be hand-edited (sqlness .result, config.md, dashboards, build.rs output, proto). - Anchor the .gitignore CLAUDE.md/AGENTS.md rules to the repo root so per-crate AGENTS.md files are tracked while root-level personal config stays ignored. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * chore: update crate AGENTS.md and fix config.md path Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * docs(agents): fix DataFusion patch layout and SQL query lifecycle order Address review feedback on #8346: - architecture-invariants: the DataFusion sub-crates pin an exact crates.io version in [workspace.dependencies] and are redirected to the fork rev in [patch.crates-io]; the two sections hold different forms, not the same rev. - frontend: the SQL query lifecycle runs the pre_parsing/post_parsing interceptors around parsing, before the per-statement permission check. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> --------- Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
4.1 KiB
flow — Agent & Contributor Guide
Navigation aid for src/flow. 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
Flownode is the stream-processing engine behind continuous aggregation / materialized views. It runs in two modes:
- Batching mode (the default and the actively developed path): splits data into time windows and periodically runs aggregation SQL through the frontend, writing results back to a sink table.
- Streaming mode (the older dataflow engine): an incremental DFIR/dataflow compute graph that processes row-level diffs.
A flow without an explicit flow_type is created as batching.
Module map
| Module | Path | Purpose |
|---|---|---|
engine |
src/flow/src/engine.rs |
FlowEngine trait: create/remove/flush/insert lifecycle |
adapter |
src/flow/src/adapter.rs, src/flow/src/adapter/ |
StreamingEngine, worker pool, dual-engine dispatch, table sources/sinks |
batching_mode |
src/flow/src/batching_mode.rs, src/flow/src/batching_mode/ |
BatchingEngine, task scheduling, time windows, frontend client, checkpoints |
compute |
src/flow/src/compute/ |
Streaming dataflow render/state |
expr |
src/flow/src/expr.rs, src/flow/src/expr/ |
Scalar/aggregate expressions and Map-Filter-Project |
plan |
src/flow/src/plan.rs |
TypedPlan (reduce/join/MFP) |
transform |
src/flow/src/transform.rs |
Substrait → flow plan |
df_optimizer |
src/flow/src/df_optimizer.rs |
SQL → DataFusion logical plan → optimized plan |
repr |
src/flow/src/repr.rs |
Row, DiffRow, Batch, RelationDesc |
server |
src/flow/src/server.rs |
gRPC Flow service, FlownodeBuilder/FlownodeInstance |
heartbeat |
src/flow/src/heartbeat.rs |
Reports flownode state/stats to metasrv |
Flow metadata lives in common-meta, not here:
src/common/meta/src/key/flow/ and src/common/meta/src/ddl/create_flow.rs.
Data flow
Frontend → Flownode (gRPC) → FlowService (server.rs) →
FlowDualEngine (adapter/flownode_impl.rs) routes by FlowType:
- Batching: marks dirty windows; a task later runs aggregation SQL via the
frontend client and writes the sink table (
batching_mode/task.rs). - Streaming: worker threads apply incremental diffs and push to the sink
(
adapter/worker.rs,compute/render.rs).
Public surface
- gRPC
Flowservice insrc/flow/src/server.rs(handle_create_remove,handle_mirror_request,handle_mark_dirty_time_window). - Sink writes for the streaming engine go through
FrontendInvoker(row_inserts,row_deletes). FlowEnginetrait insrc/flow/src/engine.rs.- Started from the
cmdcrate viaFlownodeBuilder/FlownodeInstance.
When you change X, also touch Y
- Flow definition / options: validation in
common-meta'sddl/create_flow.rsand the serializedFlowInfoValueincommon-meta'skey/flow/. - New scalar/aggregate function (
expr/): also wire up evaluation incompute/render.rs(streaming) and ensure batching SQL handles it. - Persisted flow metadata: keep
FlowInfoValuebackward compatible (serde(default)/serde(alias)). - A change to one engine often needs the mirror change in the other.
Testing
cargo nextest run -p flow
Helpers in src/flow/src/test_utils.rs (test context, test query engine).
Gotchas
- Batching vs streaming differ a lot in latency, debuggability, and code path — confirm which mode a flow uses before reasoning about it. Batching is the default and the primary target.
- Streaming workers are
!Send; cross-thread interaction goes throughWorkerHandle, not the worker directly. - Internal flow timestamps (
repr::Timestamp, ms) are not necessarily the table's time column; window functions key off the diff timestamp.
Maintenance contract
Update this file when the dual-engine routing, the gRPC surface, or the flow
metadata contract (shared with common-meta) changes.