.. include:: vars.rst .. _section-core-concepts: Core Concepts ************* This section aims to provide a deeper understanding of what |CDS| is made of, to give you the required insight to configure and use it effectively. You will learn about: - :ref:`Domain lists `—Sets the context for |CDS| in DDS domains. - :ref:`Transport `: Shows how the transports are modeled in |CDS|, which is the basis for communication with |DPs|. - :ref:`Database `: The collection of discovered |DPs| information that |CDS| maintains to represent the current state of the system. - :ref:`Forwarder `: The active logic of |CDS| that is in charge of processing the participant announcements, building the system discovery state, and providing the information to all |DPs|. .. _section-domain-lists: Domain Lists ============ A single |CDS| can forward participant announcements in *multiple DDS domains*. Yet |CDS| preserves the isolation of *DDS domain IDs* such that a |DP| only discovers other |DPs| on the same *DDS domain ID*. .. figure:: static/CdsMultiDomain.svg :figwidth: 100 % :alt: Cloud Discovery Service Multi Domain Support :name: FigureCdsMultiDomain :align: center Cloud Discovery Service Multi Domain By providing a *domain list*, you can control on which domains |CDS| operates. A domain list is a representation of domains by their IDs. You can learn more about configuring domain lists in :numref:`section-config-domain-list`. Support for multiple domain IDs can simplify system deployments, allowing a few |CDS| instances to provide discovery services for all possible expected domain IDs, even if all these domain IDs are not known in advance. .. _section-domain-list-tags: Domain Tags ----------- In large-scale systems or multi-tenant networks, such as those found in *Cloud* deployments, the isolation provided by the DDS domain ID may not be sufficient: * The number of domain IDs is limited to about 200. If more than 200 independent DDS systems needed to be deployed on a common network the domain ID would not be sufficient to provide isolation. * Managing the assignment of numeric domain IDs to independent systems or projects can be cumbersome. Numeric IDs cannot easily leverage existing organizational or project boundaries such as project name, department, organization, etc. For these reasons, DDS domain concept has been extended to include *Domain Tags*. A domain tag is a logical sub-division within a domain. It is defined as a string. |DPs| associated to different domain tags will not discover each other even if they are in the same *domain ID*. You can think of a *Domain Tag* as the DDS equivalent of a network VLAN. :numref:`FigureDomainTag` shows an overview of the domain tag concept. .. figure:: static/DomainTags.svg :figwidth: 100 % :alt: Domain Tags :name: FigureDomainTag :align: center Domain Tags A |DP| can be associated with only one domain tag. In a given domain, all the |DPs| may exchange participant announcements in order to initiate the discovery process between them. However, only |DPs| that have the **the same domain tag** will discover each other. Domain tags allow you to divide your domain in as many logically isolated spaces as you need. A domain tag is represented by a string *tag name*. You can define as many tags as spaces you need. The tag name may include any ASCII character. .. note:: The absence of a domain tag is treated like a special value of the tag. |DPs| that do not specify a domain tag will communicate only with each other. Characteristics of domain tags: - **Single Tag per Domain Participant**: A |DP| can be associated with a single domain tag. - **Immutability**: Domain tags are immutable. |DPs| specify the domain tag at creation time and it can not be modified. |CDS| understands domain tags and forwards discovery information only to |DPs| with matching domain ID **and** domain tag. :numref:`FigureCdsDomainTag` shows the domain tags' effect when |CDS| drives the discovery process. .. figure:: static/CdsDomainTags.svg :figwidth: 100 % :alt: |CDS| with domain Tags :name: FigureCdsDomainTag :align: center |CDS| with domain Tags |CDS| detects the domain tag of each |DP| and remembers that association. That way it can forward the participant announcements only to those |DPs| that belong to the same domain ID and tag. .. note:: The functionality of Domain Tags is currently only available if discovery occurs through |CDS|. If discovery occurs directly between |DP|, domain tags will be ignored. You can specify the domain tag for a |DP| at creation time via *DomainParticipantQos*. In particular, you need to propagate the well-known property ``dds.domain_participant.domain_tag,`` whose value contains the name of the tag associated to the |DP|. You can specify this property through the *PropertyQosPolicy*. Specifying the Domain Tag in XML ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following XML QoS snippet shows how to specify the domain tag within *DomainParticipantQos*. .. code-block:: xml dds.domain_participant.domain_tag TagX true .. _section-transport: Transport ========= |CDS| allows you to select which transports to use to send and receive discovery traffic. The selection of transports defines the possible locations where the service can be reached. |DPs| require this information to communicate with the service. In a *Connext DDS* application, |DPs| automatically configure the underlying transport ports based on the domain ID and the network capabilities of the host machine where the application runs. In |CDS|, this configuration is manual and explicit. .. note:: |CDS| only works with *unicast* transports. In this manual, any reference to the transport will always imply unicast. In particular, |CDS| allows you to choose: - **Transport class instance**: A *transport class* is a concrete realization of a networking transport (e.g UDP, TCP, etc). You can instantiate this class and uniquely identify it with a *transport alias*. In addition, for each instantiation you can configure properties specific to the implementation (e.g. network interfaces, receive buffer sizes, etc). - **Transport Address**: A *transport address* represents an interface for a specific transport class. For example an IP address for the UDP or TCP transport. - **Receive Port**: Identifies where the service listens to incoming data. For more information about ports, see :numref:`section-transport-about-ports`. Each transport instance-address tuple constitutes a Transport *Locator*, which is a unique data-reception endpoint. |CDS| creates send resources to put discovery traffic on the wire. *Connext DDS* uses ephemeral ports for outbound data, hence a send resource is specified by a transport instance only. |CDS| creates a send resource for each transport instance specified. |CDS| relies on the same pluggable transport framework that is available for *Connext DDS* applications to create and access transport resources. This implies you can use not only *RTI Connext* built-in transport, but also your own transport implementations. For more information, see :link_transport_plugins:`transport plugins <>` in *RTI Connext DDS Users Manual*. |DPs| can communicate with |CDS| as long as they are configured with the proper transport settings. Then they can reach a specific service instance in two ways: 1. By addressing the service instance through an :ref:`RTPS peer descriptor` which allows you to identify a DDS service in a generic way by its *locator*. |DPs| can include these in their lists of initial peers. 2. By addressing the service instance through a peer participant descriptor such that the resulting destination port computed from the domain ID of the |DP| and well-known ports configuration matches the listening port of the service. |CDS| determines how to reach back |DPs| based on the locator information they propagate as part of their participant announcements. |CDS| sends discovery traffic to a |DP| by sending data to each of its locators. .. _section-domain-list-rtps-peer-descriptor: RTPS Peer Descriptor -------------------- A peer descriptor is a string representation of a set of locators for DDS |DPs|. It provides a compact way to indicate a list of Locators where a |DP| can find other |DPs|. This is known as a **participant peer descriptor**, or simply a **peer descriptor**. *RTI Connext DDS* applications use the *participant peer descriptor* to bootstrap the participant discovery process with other |DPs|. Refer to :link_discovery_peers_config:`discovery peer configuration <>` in *RTI Connext DDS User's Manual*. The **RTPS peer descriptor** is another kind of peer descriptor that allows addressing a service with which you communicate through the *RTPS* protocol, and that does not necessarily imply the existence of a |DP|. |CDS| is an example of such a service. .. note:: The *RTPS peer descriptor* format is supported only by applications using *RTI DDS Connext* versions 5.3.0 and higher. The RTPS peer descriptor format is shown below: .. figure:: static/RtpsPeerDescriptorFormat.svg :figwidth: 100 % :alt: RTPS Peer Descriptor Format :name: FigureRtpsPeerDescriptorFormat :align: center RTPS Peer Descriptor Format :numref:`TableRtpsPeerDescriptorElements` describes all the elements in the RTPS peer descriptor. .. list-table:: RTPS peer descriptor elements :widths: 10 25 15 10 :header-rows: 0 :name: TableRtpsPeerDescriptorElements * - **Element** - **Description** - **Required** - **Default** * - ``rtps`` - Keyword to indicate the RTPS descriptor kind. - Yes - * - ``@`` - Separator. - Only when ```` is specified. - * - ```` - Specifies a transport and an address. See :link_locator_format:`locator format <>`. - No - udpv4://localhost * - ``:`` - Separator. - Only when ```` is specified. - * - ```` - RTPS Peer receive port. See :numref:`section-transport-about-ports`. - No - 7400 Example: RTPS Peer Descriptors ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. list-table:: RTPS peer descriptor for **UDP/IP** version 4 transport. :name: TableRtpsPeerDescUdp :widths: 10 4 20 4 8 :header-rows: 0 * - rtps - @ - udpv4://192.169.1.1 - : - 7400 .. list-table:: RTPS peer descriptor for a generic **Starfabric** transport. :name: TableRtpsPeerDescStarfabric :widths: 10 4 20 4 8 :header-rows: 0 * - rtps - @ - starfabric://FA::0#0/0/R - - Example: Transport setup and resulting RTPS descriptor ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Assume |CDS| is configured with the following transport settings and running in host ``CdsHost``: .. code-block:: xml udpv4 57410 |DPs| can send discovery traffic to this service by adding the following peer to their initial peer lists: .. code-block:: bash rtps@udpv4://CdsHost:57410 .. _section-transport-about-ports: About Ports ----------- Discovery traffic through RTPS relies on well-known ports to establish communication between peers. These ports are a logical concept that allow multiplexing communications at the middleware layer. It is up to the underlying transport implementation to decide how to map these logical port numbers into the physical transport address scheme. For instance, the RTI built-in UDP transport directly maps the logical port number into the physical UDP port. The port mapping is especially important in *Cloud* environments where UDP and TCP dominate the transport layer. The presence of these protocols often requires knowing details about the communication ports to properly set up application services. In a |DP|, unless explicitly configured, ports are determined automatically based on the domain ID and participant ID. Also, the port mapping is fully controlled by the underlying transport. In |CDS| the ports must be configured explicitly. Moreover, for the direct known RTI transport implementations that rely on UDP and TCP, the |CDS| service maps the (logical) receive port directly to the transport physical port. See :link_discovery_ports:`Ports Used for Discovery <>` to learn more about RTPS ports. .. _section-forwarder: Forwarder ========= The forwarder is the |CDS| component where all the discovery logic resides. Its responsibility is to build the discovery state and forward participant announcements to the peer |DPs| so that they can discover each other. :numref:`FigureCdsForwarder` shows a representation of the forwarder element of |CDS|. .. figure:: static/CdsForwarder.svg :figwidth: 100 % :alt: Participant Announcement forwarder :name: FigureCdsForwarder :align: center Participant announcement forwarder There are three main blocks that compose the forwarder: - **Receiver**: The element in charge of retrieving incoming participant announcements. This element interfaces with the *receive resources*, which provide the participant announcements received from all the peer |DPs|. - **Announcement queues**: The received participant announcements are placed in queues so they can be forwarded to the proper destinations. Participant announcements can be categorized in three different classes: - *New*: announcements from |DPs| that are considered new from the service perspective. - *Update*: announcements from |DPs| that the service has already seen but that contain content changes relative to the previous announcement from the same |DP|. For example, QoS changes in the |DP|. - *Refresh*: announcements from |DPs| that the service has already seen and that do not contain any content changes from the previously received announcement. This classification allows the forwarder to process the different categories differently, allowing you to prioritize and regulate the bandwidth used by each traffic class. - **Flow Controller**: The entity that removes announcements from the queue and forwards them to the proper destinations. The flow controller regulates the the output announcement traffic. The flow controller uses the send resources to direct the announcements to the proper |DPs|. Flow controller --------------- |CDS| incorporates a configurable flow controller that allows shaping the generated output traffic as result of forwarding participant announcements. The parameters that configure a flow controller are: - **Output capacity**: The maximum amount of announcements forwarded in a period of time. It is measured in jobs per time unit (e.g. announcements per second). Each received announcement represents a *job* to forward such announcement to all the discovered |DPs|. This parameter allows setting an upper bound to the output traffic to avoid network congestion. - **Maximum job burst**: The maximum amount of consecutive jobs that can be forwarded in a period of time. This parameter allows setting an upper limit to the output traffic peak. - **Flush period**: The period at which the flow controller attempts to forward pending announcements. .. note:: Because forwarding an announcement requires sending each announcement to multiple discovered participants, the actual output bandwidth depends on the number of participants. Operation mode ^^^^^^^^^^^^^^ The flow controller generates *job tokens* at the rate specified by the *output capacity*. Forwarding an announcement takes exactly one job token. The forwarder queues announcements upon reception and attempts to forward them as soon as tokens are available. If tokens are not available, the announcement jobs will remain in the queue in a pending state. The forwarder wakes up at every *flush period* to check for available tokens to forward the pending announcements. If tokens are generated faster than jobs are received, the flow controller accumulates the tokens for future jobs. The flow controller will accumulate no more than the *maximum job burst* tokens. .. _section-database: Database ======== |CDS| uses an internal database to keep information about remote entities. This is the information that represents the discovery state of the system. This state is maintained upon reception of discovery information. Remote entries in the database are added or removed based on the received information. The database, will release the resources for each removed entry as needed. |CDS| relies on a dedicated thread that periodically cleans up any removed state from the database. This model enhances concurrency while maintaining thread safety. This element is equivalent to the :link_database_thread:`Database Thread <>` of a |DP|.