wankai123 commented on code in PR #1234:
URL:
https://github.com/apache/skywalking-banyandb/pull/1234#discussion_r3670730770
##########
docs/design/post-trace-pipeline.md:
##########
@@ -124,7 +124,7 @@ The contract is designed around three hard requirements.
- The plugin re-exports an `ABIVersion` constant; the engine refuses to load
on mismatch with its own compiled `sdk.ABIVersion`, turning a silent miscompile
into a clear, fail-fast error. Configuration is a structured
`google.protobuf.Struct` (`SamplerPlugin.config`) set directly in the pipeline
config; the engine serializes it to canonical JSON and the plugin unmarshals
those `[]byte` into its own typed config — so the wire form is structured and
inspectable while the `.so` boundary stays a plain `[]byte`, with no shared
config struct.
- **Distribution:** operators build plugins against the released,
version-tagged `pkg/pipeline/sdk` using the **same CI image / Go version /
`-trimpath` / CGO flags** as the data node. (Background constraints,
well-documented but outside this design's verified scope: Go plugins are
**Linux/macOS only**, **cannot be unloaded** — so changing a plugin requires a
node restart, there is no hot-reload — and a plugin **panic crashes the host**
unless contained; see fail-open below.)
-**(3) Projection / column selection — spans optional, more than tags.** The
plugin declares the columns it needs up front via `Project()`, which returns a
`Projection{ Tags []string; SpanIDs bool; Spans bool }`. The engine turns
`Tags` into the **same `model.TagProjection`** the block reader already honors
(`blockMetadata.tagProjection`), so only those tag columns are decoded into
`block.tags` — literally the query engine's tag-projection path
(`trace/v1/query.proto`), not a new mechanism. Two things are **opt-in and
default off**: the span-id column (`Projection.SpanIDs`) and the heavy
span-body column (`Projection.Spans`). A subtlety in the native layout makes
this matter: `spanIDs` and `spans` are encoded **together** in one data block
(`mustWriteSpansTo`/`mustReadSpansFrom`, `banyand/trace/block.go`), so reading
span ids is **not** free — requesting either one forces a read of the spans
stream. Only `trace_id` and `MinTS`/`MaxTS` are genuinely intrinsic (they come
from `bl
ockMetadata` with no decode). So the tiers are: intrinsic-always (`trace_id`,
`minTS`/`maxTS`), opt-in-by-name (tags), and opt-in-and-default-off (the spans
stream — span ids and/or span bodies) — which is what makes spans *more*
optional than tags. The declare-up-front handshake matches the
projection-pushdown contracts in [DuckDB's C table
API](https://duckdb.org/docs/stable/clients/c/table_functions)
(`duckdb_init_get_column_index`) and [DataFusion's
`TableProvider::scan`](https://datafusion.apache.org/library-user-guide/custom-table-providers.html)
(`projection: Option<&Vec<usize>>`). `min_duration`-style checks are free from
`minTS`/`maxTS`, and an error predicate is just a projected tag (e.g.
`is_error`), so a plugin that requests neither tags, span ids, nor span bodies
stays on the merge raw fast path (`mustReadRaw` → `mustWriteRawBlock`, §7.1)
and pays no decode at all.
+**(3) Projection / column selection — spans optional, more than tags.** The
plugin declares the columns it needs up front via `Project()`, which returns a
`Projection{ Tags []string; SpanIDs bool; Spans bool }`. The engine turns
`Tags` into the **same `model.TagProjection`** the block reader already honors
(`blockMetadata.tagProjection`), so only those tag columns are decoded into
`block.tags` — literally the query engine's tag-projection path
(`trace/v1/query.proto`), not a new mechanism. Two things are **opt-in and
default off**: the span-id column (`Projection.SpanIDs`) and the heavy
span-body column (`Projection.Spans`). A subtlety in the native layout makes
this matter: `spanIDs` and `spans` are encoded **together** in one data block
(`mustWriteSpansTo`/`mustReadSpansFrom`, `banyand/trace/block.go`), so reading
span ids is **not** free — requesting either one forces a read of the spans
stream. Only `trace_id` and `MinTS`/`MaxTS` are genuinely intrinsic (they come
from `bl
ockMetadata` with no decode). So the tiers are: intrinsic-always (`trace_id`,
`minTS`/`maxTS`), opt-in-by-name (tags), and opt-in-and-default-off (the spans
stream — span ids and/or span bodies) — which is what makes spans *more*
optional than tags. The declare-up-front handshake matches the
projection-pushdown contracts in [DuckDB's C table
API](https://duckdb.org/docs/stable/clients/c/table_functions)
(`duckdb_init_get_column_index`) and [DataFusion's
`TableProvider::scan`](https://datafusion.apache.org/library-user-guide/custom-table-providers.html)
(`projection: Option<&Vec<usize>>`). an error predicate is just a projected
tag (e.g. `is_error`), and while `minTS`/`maxTS` are free, they are the spread
of per-row *start* timestamps — **not** a trace duration (they are 0 for a
single-row trace), so a duration predicate must project the schema's own
start/duration tags, so a plugin that requests neither tags, span ids, nor span
bodies stays on the merge raw fast path (`mustRea
dRaw` → `mustWriteRawBlock`, §7.1) and pays no decode at all.
Review Comment:
Good catch, and it was worse than the capitalization. Fixed in eb1e7d69.
The paragraph previously claimed `min_duration`-style checks were free from
`minTS`/`maxTS`, which is wrong — those are the spread of per-row *start*
timestamps, not a duration (and `0` for a single-row trace). Replacing that
clause left the next one starting lowercase mid-paragraph *and* chained two
`so` clauses that no longer followed from each other:
> ...). an error predicate is just a projected tag (e.g. `is_error`), and
while `minTS`/`maxTS` are free, they are the spread of per-row *start*
timestamps — **not** a trace duration (they are 0 for a single-row trace), so a
duration predicate must project the schema's own start/duration tags, so a
plugin that requests neither tags...
Now split into two sentences that each say one thing:
> An error predicate is just a projected tag (e.g. `is_error`), while a
duration predicate is **not** free: `minTS`/`maxTS` are the spread of per-row
*start* timestamps, not a trace duration (they are 0 for a single-row trace),
so it has to project the schema's own start and duration tags. A plugin that
requests neither tags, span ids, nor span bodies stays on the merge raw fast
path...
I also swept the rest of the diff in that file for the same splice pattern
(lowercase after a sentence break, doubled connectives) — this was the only
instance.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]