Jump to content

Standalone ChannelRuntime Clients

From RidgeRun Developer Wiki

🚧 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.

Contents Pin





Standalone ChannelRuntime Clients

A standalone client is a separate program that publishes to a graph input or subscribes to a graph output. It uses the graph's accepted endpoint catalog to select the endpoint and payload contract, then manages its own data loop and shutdown.

Begin with External Endpoints and Endpoint Catalogs to create and save the catalog. The client examples here assume that the graph and its transport services are deployed separately.

The Channels and HoloMQ page explains the process-boundary transport choices. For Tensor or schema payloads, use the representation and ownership vocabulary from Tensor Contracts and Memory Types and Allocation Ownership and Tensor Pools.

Choose the client role

The endpoint direction determines which client role to create:

Graph boundary Standalone client Typical use
Graph import Publisher Sensor service, camera process, or upstream producer.
Graph export Subscriber Recorder, display, monitoring process, or downstream consumer.
Descriptor-backed import or export Tensor-schema publisher or subscriber Image, IMU, or application schema with one or more Tensor fields.

Load the exact catalog used by the graph. load_json() reads the catalog file, and ChannelRuntime::create() creates the client runtime. Check both results before creating an endpoint.

Payload Factory
Scalar, declared raw POD, or ordinary generated schema create_publisher<T>() for an import or create_subscriber<T>() for an export.
Raw Tensor The Tensor overload, with the finite boundary and storage rules from the catalog.
Descriptor-backed schema create_tensor_schema_publisher<Payload>() or create_tensor_schema_subscriber<Payload>(), with every Tensor field covered.

The factory checks endpoint identity, role, payload layout, capacities, capabilities, and attachment policy. A URI or familiar endpoint name alone is not enough to establish a compatible client.

Build a checked subscriber

The following complete client reads one uint32_t value from an export named measurements-out. It expects the graph to be running and the catalog to be available in the current directory:

#include <chrono>
#include <cstdint>
#include <iostream>
#include <holoscan/channel/endpoint_catalog.hpp>
#include <holoscan/channel/runtime.hpp>

int main() {
  auto catalog = holoscan::ChannelEndpointCatalog::load_json(
      "endpoint-catalog.json");
  if (!catalog) {
    return 1;
  }

  auto runtime = holoscan::ChannelRuntime::create();
  if (!runtime) {
    return 2;
  }

  auto subscriber = runtime->create_subscriber<std::uint32_t>(
      *catalog, "measurements-out");
  if (!subscriber) {
    return 3;
  }

  const auto deadline = std::chrono::steady_clock::now()
                        + std::chrono::seconds{10};
  auto sample = subscriber->wait_and_receive_sample(deadline);
  if (!sample) {
    return 4;
  }

  std::cout << sample->data << '\n';
  return subscriber->close() ? 0 : 5;
}

The ten-second deadline is local to this program. It does not start the graph or extend the endpoint's accepted contract. A publisher follows the same setup sequence, then emits values with metadata that matches the payload contract.

Interpret wait and publication results

A receive wait and a publication result answer different questions. Check the returned value before reading it or reporting a successful operation:

Result Application response
Timeout The current wait expired. Keep the endpoint usable and retry only under an intentional application budget.
Interrupted or cancelled Stop this wait and decide whether the program should continue or close the endpoint.
Closed or end-of-stream Stop receiving through this endpoint generation and release its data.
Stale endpoint or changed producer Rebuild the client through the catalog factory when the endpoint API requires it.
Other error Report the setup, protocol, readiness, or resource problem. Do not treat it as an empty queue.

For a publisher, a successful result counts the recipients reached by the operation. It does not mean that every recipient finished processing the value. Refreshing a connection snapshot can help an application decide whether to attempt a publication, but the publication result remains authoritative for that operation.

Keep runtime and received data alive

ChannelRuntime must outlive its ordinary endpoints, descriptor-backed received Tensors, derived views, and asynchronous device work that uses those values. Keep an owning Tensor or received bundle alive through the last read, copy, export, or stream operation.

One subscriber supports one waiting thread. Keep its facade alive and unmoved while waiting. For a descriptor-backed value with multiple Tensor fields, use the bundle receive path described in Descriptor-Tensor External Topics.

Close in the right order

For a finite publisher, check publisher.close() and interpret its outcome. Ordered end-of-stream is different from process exit, timeout, or object destruction. A subscriber close is local cleanup and does not finish the producer's stream.

Stop and join waiters before closing their endpoint. Release received samples, Tensor views, destinations, and streams before destroying the runtime. Do not retry a publication after an uncertain submission unless the API guarantees that the operation was not submitted and the application has fresh publication authority.


Continue the flow


A client does not launch the graph
Start the graph owner, discovery service, and transport service as separate deployment steps. A successful catalog load only proves that the file can be read; it does not prove that a peer is present.


Related examples and concepts

Examples

Concepts

Further reading

Source


Cookies help us deliver our services. By using our services, you agree to our use of cookies.