.. 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:`Forwarder `: Explains 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|. - :ref:`Database `: Describes the collection of discovered |DP| information that |CDS| maintains to represent the current state of the system. .. _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| with the same *DDS domain ID*. .. figure:: static/CdsMultiDomain.svg :figwidth: 100 % :alt: Cloud Discovery Service works with Multiple Domains :name: FigureCdsMultiDomain :align: center Cloud Discovery Service works with Multiple Domains 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 :ref:`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 maximum number of domain IDs is limited and not sufficiently large. In deployments that require many independent DDS systems in 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, the 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 same domain tag** will discover each other. Domain tags allow you to divide your domain into 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 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 DomainParticipant**: 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 cannot 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. 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 with the |DP|. You can specify this property through the *PropertyQosPolicy*. For more information, see :link_domain_tags:`Choosing a Domain Tag <>` in *RTI Connext DDS Users Manual*. Specifying the Domain Tag in XML ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following XML 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 for incoming data. For more information about ports, see :ref:`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| builtin transports, 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 |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 *peer descriptor* to bootstrap the participant discovery process with other |DPs|. Refer to :link_discovery_peers_config:`discovery peer configuration <>` in the |CORE_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 :ref:`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 on 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 builtin 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, |CDS| 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 The forwarder is composed of three main blocks: - **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 their proper destinations. Participant announcements can be categorized in three 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 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, which allows shaping the generated output traffic as a 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 units (e.g., announcements per second). Each received announcement represents a *job* to forward the announcement to all 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, which 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|.