Skip to main content

attach

Function attach 

Source
pub fn attach(parent: &Arc<RwLock<Component>>, child: &Arc<RwLock<Component>>)
Expand description

Attach a child component to a parent.

Computes the child’s effective labels by composing the parent’s effective labels with the child’s own labels. Adds the child to the parent’s children list and sets the child’s parent reference.

Label-ownership invariant. A dimensional label name is owned by exactly one component in any ancestor chain: once a name is set on a component at initialization, no descendant may redeclare it — neither with a differing value (which would silently corrupt the dimensional cell) nor with the same value (which makes ownership ambiguous). The session tier owns session, the execution tier owns {exec_id, workload}, the phase tier owns {phase, …for_each}, and so on down — each component declares ONLY the labels it introduces. This check enforces that at attach time (init, not per-cycle): a collision is a construction bug and panics with both label sets named, rather than letting the composition silently pick a winner.

Concurrent-sibling invariant. The rule above is vertical — it constrains a child against its ANCESTORS. Two SIBLINGS declaring the same own-labels compose byte-identical effective_labels, and the same family registered on each then yields two instruments sharing one metric identity, which the per-component duplicate-family check cannot see because they are different components.

That is rejected only when the siblings are alive AT THE SAME TIME. Sequential reuse is legitimate: an iteration whose values repeat (the fib comprehension yields n=1 twice) re-materialises the same identity, which is one identity sampled again over time, not a second identity. An unconditional check was implemented and rejected for exactly that reason.

Liveness is tracked by a token each component holds until it reaches ComponentState::Stopped; the parent indexes Weak clones per own-label set. So the check needs no lock on any child, costs a lookup in one bucket, and cleans up with no teardown pass — a stopped or dropped component’s claim simply expires.