Tee is a misnomer: it is a passthrough counter, and the docs claim it is a 1-to-N fanout #48

Open
opened 2026-07-14 15:40:05 +00:00 by p13marc · 1 comment
p13marc commented 2026-07-14 15:40:05 +00:00 (Migrated from github.com)

Tee does not tee. It is a 1-in/1-out passthrough counter, and the module docs claim the opposite.

src/elements/flow/tee.rs:41-105:

impl Element for Tee {
    fn process(&mut self, buffer: Buffer) -> Result<Option<Buffer>> {
        self.count += 1;
        self.bytes += buffer.len() as u64;
        Ok(Some(buffer))          // one buffer in, one buffer out
    }

Its own doc comment is honest (tee.rs:9-13):

Unlike a true multi-output tee (which would need special pipeline support), this Tee element passes the buffer through and tracks statistics. For true multi-output fanout, use multiple links from a single source node in the pipeline graph, which the executor handles by cloning buffers.

But the module documentation is not. src/elements/flow/mod.rs:8:

/// - [`Tee`]: 1-to-N fanout (duplicates buffers)

which is false. And src/elements/mod.rs:18 advertises "Queue, tee, funnel, selectors, concat, valve" in a list of flow elements, implying a tee is among the tools available. funnel.rs:15 compounds it: "This is the complement to Tee which splits one output to many."

The real fan-out mechanism — multiple link() calls from one src-pad, which the executor broadcasts to a Vec<AsyncSender> with refcounted buffer clones — is genuinely good and genuinely documented nowhere near here.

Ask

  1. Rename to Probe / Inspect (what it actually is), or at minimum stop calling it a fanout.
  2. Fix flow/mod.rs:8 and funnel.rs:15.
  3. Document the real fan-out mechanism where someone looking for a tee will find it — including the constraint that the string-parse grammar cannot express it (it's a strictly linear chain), so fan-out requires the programmatic API.

Cost me a wrong turn while auditing 0.2.0 for the zensight sensor: I assumed from the docs that a tee existed and that fan-out was therefore an element-level concern, when in fact fan-out already works and the element is a red herring.

`Tee` does not tee. It is a 1-in/1-out passthrough counter, and the module docs claim the opposite. `src/elements/flow/tee.rs:41-105`: ```rust impl Element for Tee { fn process(&mut self, buffer: Buffer) -> Result<Option<Buffer>> { self.count += 1; self.bytes += buffer.len() as u64; Ok(Some(buffer)) // one buffer in, one buffer out } ``` Its own doc comment is honest (`tee.rs:9-13`): > Unlike a true multi-output tee (which would need special pipeline support), this Tee element passes the buffer through and tracks statistics. For true multi-output fanout, use multiple links from a single source node in the pipeline graph, which the executor handles by cloning buffers. But the module documentation is not. `src/elements/flow/mod.rs:8`: ``` /// - [`Tee`]: 1-to-N fanout (duplicates buffers) ``` which is false. And `src/elements/mod.rs:18` advertises "Queue, tee, funnel, selectors, concat, valve" in a list of flow elements, implying a tee is among the tools available. `funnel.rs:15` compounds it: "This is the complement to `Tee` which splits one output to many." The real fan-out mechanism — multiple `link()` calls from one src-pad, which the executor broadcasts to a `Vec<AsyncSender>` with refcounted buffer clones — is genuinely good and genuinely documented nowhere near here. ## Ask 1. Rename to `Probe` / `Inspect` (what it actually is), or at minimum stop calling it a fanout. 2. Fix `flow/mod.rs:8` and `funnel.rs:15`. 3. Document the real fan-out mechanism where someone looking for a tee will find it — including the constraint that **the string-parse grammar cannot express it** (it's a strictly linear chain), so fan-out requires the programmatic API. Cost me a wrong turn while auditing 0.2.0 for the zensight sensor: I assumed from the docs that a tee existed and that fan-out was therefore an element-level concern, when in fact fan-out already works and the element is a red herring.
p13marc commented 2026-07-14 15:52:51 +00:00 (Migrated from github.com)

Update: breaking changes are on the table, so drop the "rename or document" hedge — rename it.

Tee is a 1-in/1-out passthrough counter. Anything called Tee in a media pipeline promises 1-to-N fanout, and flow/mod.rs:8 explicitly (and falsely) claims it delivers exactly that. Documentation cannot fix a name that actively misleads — I went looking for the fan-out mechanism, found a type called Tee, and had to read its source to discover that the real mechanism was multiple link() calls and that this type had nothing to do with it.

Probe or Inspect. Then fix flow/mod.rs:8 and funnel.rs:15 ("the complement to Tee which splits one output to many" — it isn't), and document the real fan-out mechanism where someone hunting for a tee will actually land.

**Update: breaking changes are on the table**, so drop the "rename **or** document" hedge — **rename it.** `Tee` is a 1-in/1-out passthrough counter. Anything called `Tee` in a media pipeline promises 1-to-N fanout, and `flow/mod.rs:8` explicitly (and falsely) claims it delivers exactly that. Documentation cannot fix a name that actively misleads — I went looking for the fan-out mechanism, found a type called `Tee`, and had to read its source to discover that the real mechanism was multiple `link()` calls and that this type had nothing to do with it. `Probe` or `Inspect`. Then fix `flow/mod.rs:8` and `funnel.rs:15` ("the complement to `Tee` which splits one output to many" — it isn't), and document the real fan-out mechanism where someone hunting for a tee will actually land.
Sign in to join this conversation.
No description provided.