One edge, a whole subtree (L4 graph)¶
There is no separate “wildcard subscribe” verb — and no textual path wildcard, since *
may not appear in a NAME. Every subscription is a subtree subscription
(RFC-0005 — subtree subscriptions):
an edge on /dev observes writes to /dev and to every descendant of it. This example
registers /dev/a/temp and /dev/b/temp, subscribes once on /dev, and writes both
leaves.
What to notice¶
One
SUBSCRIBERcovers a composite. Subscribing to a parent replaces one edge per leaf, which is the point on a node whose subscriber arena is measured in kilobytes.Propagation is one hop plus upward bubbling. A write fans out to the written vertex’s own subscriptions plus each ancestor’s, so the walk is strictly rootward and bounded by tree height — it never descends.
The delivered value is the descendant’s write as-is. The producer’s frame arrives at its produced granularity; the subscription carries no “which leaf” field. Any provenance a consumer needs must travel in the delivered data (RFC-0003), never be inferred from the edge. Remote delivery is where that becomes a wire question; in-process it is the application’s own encoding.
own_subsat the leaf is zero, and that is not “nobody is listening”. A subtree subscriber is counted by the ancestor bookkeeping (listeners_above), not by the leaf’s own slot count — the example asserts both, because a producer that gated its publish onown_subswould silently drop every subtree subscriber.has_subscribersis the question to ask.
Source¶
1/*
2 * SPDX-License-Identifier: Apache-2.0
3 * SPDX-FileCopyrightText: Copyright 2026 avatarsd LLC
4 */
5
6/**
7 * @file
8 * @brief One subscription edge covers a whole subtree — RFC-0005 vertical bubbling.
9 *
10 * Every subscription is a subtree subscription: an edge on `/dev` observes writes to
11 * `/dev` AND to every descendant, so a composite needs one `SUBSCRIBER` rather than one
12 * per leaf. The delivered value is the descendant's written TLV **as-is**, which is why
13 * the subscriber cannot infer WHICH leaf produced it from the subscription — provenance
14 * must ride in the delivered data (RFC-0003).
15 *
16 * Runs under ctest as `example_sub_subtree`; it self-checks and returns non-zero on any
17 * mismatch.
18 */
19
20#include <cstddef>
21#include <cstdint>
22#include <cstdio>
23
24#include "libtracer/tracer.hpp"
25
26namespace {
27
28using tr::graph::path_t;
29using tr::graph::role_t;
30
31/** @brief A one-byte VALUE view over @p b (one heap segment). */
32tr::view::view_t value_byte(std::uint8_t b) {
33 tr::view::segment_ptr_t seg = tr::view::heap_alloc(1);
34 seg->bytes[0] = std::byte{b};
35 return tr::view::view_t::over(std::move(seg));
36}
37
38/** @brief Record a failed expectation on @p ok and report it. */
39void check(bool& ok, bool cond, const char* what) {
40 if (!cond) {
41 std::printf(" [FAIL] %s\n", what);
42 ok = false;
43 }
44}
45
46} // namespace
47
48int main() {
49 tr::graph::graph_t g;
50 (void)g.register_vertex(path_t("/dev"), role_t::STORED_VALUE);
51 const tr::graph::vertex_handle_t a =
52 g.register_vertex(path_t("/dev/a/temp"), role_t::STORED_VALUE);
53 const tr::graph::vertex_handle_t b =
54 g.register_vertex(path_t("/dev/b/temp"), role_t::STORED_VALUE);
55
56 int seen = 0;
57 auto on_dev = [&](const tr::view::rope_t& v) {
58 ++seen;
59 // The value arrives as written; the edge carries no "which leaf" field.
60 std::printf(" delivery %d: %u\n", seen,
61 std::to_integer<std::uint8_t>(v.only().bytes()[0]));
62 };
63 const auto sub = g.subscribe(path_t("/dev"), on_dev); // ONE edge, on the parent
64
65 (void)g.write(a, value_byte(0x11));
66 (void)g.write(b, value_byte(0x22));
67
68 bool ok = true;
69 check(ok, sub.has_value(), "one subscribe on the parent");
70 check(ok, seen == 2, "both descendants' writes bubbled to that one edge");
71 check(ok, g.own_subs(a) == 0, "the leaf itself carries NO own subscriber slot");
72 check(ok, g.has_subscribers(a), "but a delivery there would reach an ancestor subscriber");
73 std::printf("RESULT %s (own_subs(/dev/a/temp)=%u, has_subscribers=%d)\n", ok ? "ok" : "FAILED",
74 g.own_subs(a), static_cast<int>(g.has_subscribers(a)));
75 return ok ? 0 : 1;
76}
See also: graph module · graph model · communication flows · subscribe to one vertex.