Skip to content

feat(foxglove,ros2,parser_ros): lazy per-topic subscription (SDK 0.15.0)#191

Draft
Alvvalencia wants to merge 5 commits into
mainfrom
feature/lazy-subscription
Draft

feat(foxglove,ros2,parser_ros): lazy per-topic subscription (SDK 0.15.0)#191
Alvvalencia wants to merge 5 commits into
mainfrom
feature/lazy-subscription

Conversation

@Alvvalencia

Copy link
Copy Markdown
Contributor

Plugin side of lazy subscription (SDK: PlotJuggler/plotjuggler_sdk#141, host: PlotJuggler/PJ4#348).

  • foxglove: dialog persists the full channel catalog (all_channels); advertises everything at start, subscribes only the dialog-selected eager floor; reconciles against the host's desired set via the pure, unit-tested computeSubscriptionOps; handles mid-stream advertise/unadvertise + reconnect; OK no longer requires a selection (old host + empty selection fails loudly).
  • ros2: ~1 Hz in-poll graph discovery + full-graph advertise (schemas cached per type); reconcile creates/destroys GenericSubscriptions — unsubscribed topics cost zero DDS traffic. Poll-thread destruction while the executor spins is flagged for per-distro stress verification (comment in code).
  • parser_ros: describeSchemaColumns walks the rosx_introspection schema tree so advertised-but-unsubscribed CDR topics show draggable fields with zero data; stands down for value-dependent types (string-to-number toggles) and topic-conditional object-only overrides. Consistency tests pin manifest == parse emission.

SDK_VERSION → 0.15.0; extern/plotjuggler_core pins the SDK PR branch (moves to the tagged release before merge). Requires host+plugins rebuilt together (see the SDK PR's break marker). Pending: parser_protobuf manifest.

Suites green: foxglove_protocol_test (incl. reconcile ops), parser_ros 4/4 (2 new manifest tests), ros2 builds per-distro (jazzy).

🤖 Generated with Claude Code

https://claude.ai/code/session_01WUAom7BH7x39mRZFhBw79z

Alvvalencia and others added 5 commits July 6, 2026 13:15
Both streamers declare kCapabilityLazySubscription: they connect without
subscribing, advertise their full topic catalog to the host, and reconcile
per-topic subscriptions against the host's declarative desired-active set
(dialog selection = always-on eager floor). On a pre-0.15 host the
advertise fails with the distinct fallback error and today's eager
behavior is unchanged.

- foxglove: dialog persists the FULL channel catalog (all_channels config
  key — the stolen socket never re-receives the advertise burst); onStart
  advertises all supported channels and subscribes only the eager floor;
  onActiveTopicsChanged reconciles via the pure computeSubscriptionOps
  diff (new in foxglove_protocol.hpp, unit-tested); mid-stream
  advertise/unadvertise re-advertises + reconciles; reconnect rebuilds the
  catalog from the fresh burst while host_active_ persists. OK button no
  longer requires a selection.
- ros2: in-source graph discovery every ~20 poll ticks (~1 s) advertises
  the whole graph (ros2msg schemas cached per type); reconcile
  creates/destroys GenericSubscriptions on the poll thread — dropping one
  genuinely stops DDS delivery; empty selection allowed in lazy mode.
- parser_ros: describeSchemaColumns walks rosx_introspection's schema
  tree and emits the flattened scalar-column manifest (types exactly as
  variantToValueRef emits; arrays and specialized builtin-object schemas
  stand down) so advertised-but-unsubscribed CDR topics show draggable
  fields with zero data. Consistency test pins manifest == parse emission.
- SDK_VERSION 0.14.0 -> 0.15.0; extern/plotjuggler_core -> d338f44
  (lazy-subscription SDK).

Builds: foxglove + ros2 (jazzy inner) + parser_ros standalone vs
plotjuggler_sdk/0.15.0; foxglove_protocol_test and parser_ros suites green.

Pending: parser_protobuf manifest (foxglove protobuf channels stay
field-less until first data).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WUAom7BH7x39mRZFhBw79z
…policy

The 20 s grace let two heavy topics coexist when the second was already
plotted before the first was removed (eager eviction only fires on 0→1
activations). Object topics (pointclouds, images, video, grids — classified
at advertise pre-bind) now go Active→Idle the instant their last consumer
disappears; the grace window + eager eviction remain for light scalar
topics only, where re-drop churn protection matters and the cost is small.

AdvertisedTopic carries object_topic; StreamingSourceManager forwards the
heavy set; TopicUsageRegistry::setAdvertisedTopics gains the heavy names.
Test: heavy topic drops immediately even while others stay active; light
topic still drains in the same situation. 250/250 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WUAom7BH7x39mRZFhBw79z
…e chain

recompute refs → registry active-set change → set_active_topics push.
Used to verify the E2E wire timing (immediate heavy unsubscribe).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WUAom7BH7x39mRZFhBw79z
- parser_ros manifest: omit STRING columns when string-to-number toggles
  are on (value-dependent type cannot be pre-declared) and stand down for
  topic-conditional object-only overrides (robot_description) — both
  cases previously pre-created columns parse() would contradict or never
  populate. Two new tests.
- foxglove: old host + empty selection now fails loudly at onStart
  (mirrors ros2) instead of silently streaming nothing.
- ros2: documented the poll-thread GenericSubscription destruction
  contract (per-distro stress verification flagged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WUAom7BH7x39mRZFhBw79z
…lling-dedup commit

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WUAom7BH7x39mRZFhBw79z
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant