* feat: add `ingest_rows_rate_limit` database option Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * feat: add `InsertLimitInterceptor` hook to `Inserter` Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * fix: attribute insert limit checks to the target table's database Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> * refactor: unify write admission through metering Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: enforce write admission for pending row batches Signed-off-by: shuiyisong <xixing.sys@gmail.com> * feat: distinguish internal requests for ingestion metering Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: admit split ingestion requests once per database Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: OpenTSDB throws error reason Signed-off-by: shuiyisong <xixing.sys@gmail.com> * chore: use meter crate main rev Signed-off-by: shuiyisong <xixing.sys@gmail.com> * fix: exclude database ingest rate limit from table options Signed-off-by: shuiyisong <xixing.sys@gmail.com> * refactor: reserve channel 255 for internal requests Signed-off-by: shuiyisong <xixing.sys@gmail.com> --------- Signed-off-by: Lei, HUANG <ratuthomm@gmail.com> Signed-off-by: shuiyisong <xixing.sys@gmail.com> Co-authored-by: Lei, HUANG <ratuthomm@gmail.com>
3.3 KiB
flow — Agent & Contributor Guide
Navigation aid for src/flow. Keep it short and point to code. Paths are
relative to the repository root.
Repo-wide rules that apply to here: .agents/architecture-invariants.md.
What this crate does
Flownode provides two flow profiles:
- Streaming mode: a single stateless DataFusion query profile. Each mirror
insert is materialized as a transient input table, executed against the
retained logical plan, and written directly to the sink through
batching_mode::frontend_client::FrontendClient. - Batching mode: splits data into time windows and periodically runs aggregation SQL through the frontend, writing results back to a sink table.
Users cannot select a mode directly: flow_type is a reserved internal option.
StatementExecutor::determine_flow_type in src/operator/src/statement/ddl.rs
owns current mode selection. FlowDualEngine defaults missing internal
flow_type metadata to batching for compatibility. Read those paths before
changing routing rules.
Module map
| Module | Path | Purpose |
|---|---|---|
engine |
src/flow/src/engine.rs |
FlowEngine lifecycle contract |
adapter |
src/flow/src/adapter.rs, src/flow/src/adapter/ |
Stateless streaming execution, dual-engine dispatch, shared source schema/default normalization, and sink creation |
batching_mode |
src/flow/src/batching_mode.rs, src/flow/src/batching_mode/ |
BatchingEngine, scheduling, time windows, frontend client, and checkpoints |
repr |
src/flow/src/repr.rs |
Shared row and relation schema representations |
server |
src/flow/src/server.rs |
gRPC Flow service and flownode builders |
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:
- Streaming: mirror rows are normalized against the source schema, evaluated by
the retained stateless DataFusion plan, and sent to the sink via
FrontendClient. - Batching: marks dirty windows; a task later runs aggregation SQL via the frontend client and writes the sink table.
FlowType::Streaming and mirror routing are shared contracts; preserve both
when changing dispatch. Preserve batching behavior and the shared schema,
default, and sink-creation helpers.
Public surface
- gRPC
Flowservice insrc/flow/src/server.rs. - Local streaming sink writes and batching query execution use
Channel::Internalso meter collectors can account for sink writes without charging ingestion quota. FlowEnginetrait insrc/flow/src/engine.rs.- Started from the
cmdcrate viaFlownodeBuilder/FlownodeInstance.
Testing
cargo nextest run -p flow
Stateless streaming tests are under src/flow/src/adapter/stateless.rs.
Gotchas
- Batching and streaming differ in latency and state. Confirm the selected mode before reasoning about a flow.
- Streaming is finite and stateless per mirror request; it has no worker graph, background runtime, or replay state.
- Internal flow timestamps and table time columns are separate contracts.