Dynamic External Peers
🚧 Documentation is under development
The Holoscan SDK guide is currently under active development. Some sections may be incomplete or change without notice.
Questions? Contact RidgeRun or email to support@ridgerun.com.
-
Overview
-
Build, Run, and Validate
-
Core Concepts
-
Operators and Graphs
-
Tensor Data and Memory
-
Interprocess Communication
-
-
Application and Operator Development
- Building an HSDK Application
- Writing a Minimal Operator
- Typed Parameters and Configuration
- Reading, Writing, and Forwarding Data
- Writing Tensor Operators
- Complete Operator Patterns
- Authoring Runtime Behavior
- Runtime Parameter Updates
- Lifecycle Callbacks and Restart Control
- Performance and Debugging
- SDK Source Map
-
Operator Reference
-
Core Operators
-
Holoscan Camera
-
Holoscan RidgeRun
- Overview
- Build and Installation
- ArgusCameraOp
- V4L2SourceOp
- V4L2UserPtrSourceOp
- BgraToPlanarTensorOp
- RawBayerToBgraOp
- RawBayerToYoloTensorOp
- YuyvToBgraOp
- TensorRtInferenceOp
- DrmDisplayOp
- DrmBgraDisplayOp
- X11DisplayOp
- CudaCompositorOp
- DepthColorizerOp
- FakesinkOp
- FrameSkipperOp
- InterprocessSrcOp
- TestPatternOp
-
-
Migration from Holoscan 4.x
-
Examples
-
Core
-
Holoscan Camera
-
Holoscan RidgeRun
-
-
Benchmark and Use Cases
-
Holoscan vs GStreamer
- Overview
-
Capture and Display
-
Capture and Inference
- Compare the workloads
- Implemented Applications
- Framework Selection
- Interprocess
-
Dynamic External Peers
An external publisher or subscriber can appear, disappear, or be replaced while the graph is running. The graph's endpoint contract stays fixed, while peer presence and transport generation change over time.
The application needs to answer four questions: can the graph start without the peer, what does a connection snapshot mean, how should each operation be retried, and what action is allowed after end-of-stream or a stale generation? Start with External Endpoints and Endpoint Catalogs for the fixed boundary and with Standalone ChannelRuntime Clients for client creation.
The Operator Lifecycle page explains application-controlled restart authority inside a graph. The Allocation Ownership and Tensor Pools page explains why outstanding samples and Tensor backing must remain alive during a peer change.
Fix the boundary before peers arrive
Declare the topic, stable endpoint name, payload identity, finite capacity, and peer policy while composing the graph. The compiled plan and its catalog define what a replacement peer must satisfy. Reconnecting does not change the Tensor shape, schema fields, memory rules, or queue budget.
For a raw Tensor, put the finite boundary in TopicOptions::tensor before calling Graph::import_topic() or Graph::export_topic(). For an image or IMU schema, cover every Tensor field with Descriptor-Tensor External Topics.
Choose optional or required startup
PeerRequirement expresses whether startup requires an observed peer. An optional peer lets the graph start while the external process is absent. It does not create a sample, remove backpressure, or guarantee that a later publication will be delivered.
A required peer uses TopicAttachPolicy with a positive finite wait:
input_options.attach = holoscan::TopicAttachPolicy{
.peer = holoscan::PeerRequirement::kRequired,
.max_wait = std::chrono::seconds{2},
};
// Apply input_options before graph.import_topic().
The wait is a cold-path attachment decision. A caller can choose a shorter local timeout, but it cannot extend the accepted endpoint budget. An absent peer remains an ordinary runtime condition after optional startup.
Treat presence as a hint
A publisher can refresh its observed connection snapshot with update_connections() and inspect has_subscribers(). The snapshot helps avoid an unnecessary attempt, but it does not reserve a recipient for the next publication.
auto refreshed = publisher.update_connections();
if (!refreshed) {
return holoscan::make_unexpected(std::move(refreshed).error());
}
const bool observed_peer = publisher.has_subscribers();
// Check the actual publication result after this advisory snapshot.
Always check the publication result. Retry only a documented pre-submit outcome, such as a proven kNotReady or kBackpressured result. A partial or indeterminate result may already have reached a recipient, so repeating it can duplicate data.
Subscribers should use their checked receive or wait path. A wake means that the application can try to receive; it does not prove that a complete value is still queued. Keep the endpoint alive during the wait and use one waiting thread per subscriber.
Separate timeout, end-of-stream, and replacement
These events need different application responses:
| Observation | Meaning | Next action |
|---|---|---|
| Timeout | No value arrived before the current wait expired. | Keep the endpoint usable or stop according to the application's own deadline. |
| Peer disappeared | The observed connection is no longer available. | Refresh or wait for a new peer; do not count presence as delivery. |
| End-of-stream | The current producer generation finished in an ordered way. | Drain accepted data, close the generation, and follow the admitted replacement path. |
| Stale producer generation | The catalog endpoint now refers to a changed producer incarnation. | Rebuild the client through the matching catalog factory when required by the API. |
| Different payload or graph contract | The replacement does not satisfy the accepted plan. | Create and deploy a new compatible plan and catalog. |
A finite producer should check publisher.close() when it finishes. Process exit, silence, or subscriber close does not publish end-of-stream. A subscriber close is local cleanup and does not finish the producer's stream.
Replace a peer within the accepted lifecycle
When the client API reports a stale producer generation, release or retain outstanding values according to their ownership rules, then create the replacement endpoint through the catalog factory. Keep Tensor backing, destination buffers, and CUDA streams alive until queued work finishes. A new peer still has to satisfy the same field, layout, memory, and capacity contract.
Some graph configurations admit an explicit lifecycle restart with finite generation and transaction resources. Use that path only when the compiled plan declares it. A new publisher on the same URI does not automatically reactivate an import that has already accepted end-of-stream.
When the payload, capacity, topic contract, or graph connection changes, author and compile a new plan. Editing a catalog file does not change a live graph's resource obligations.
Check the boundary in order
| Observation | Check next |
|---|---|
| Attachment fails | Catalog file, endpoint name, import/export role, schema or Tensor layout, capabilities, and attachment budget. |
| Optional attachment succeeds but no value arrives | Graph and transport services, connection refresh, producer result, queue state, and acquisition metadata when required. |
| Publication reports backpressure or resource exhaustion | Queue and retention budgets, held loans or samples, and the operation's retry authority. |
| Receive reports end-of-stream or a stale generation | Drain and close semantics, then the admitted rebind or lifecycle path. |