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 SUBSCRIBER covers 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_subs at 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 on own_subs would silently drop every subtree subscriber. has_subscribers is 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.