7. Quality of Service (QoS)

The following section explains how to set the Quality of Service (QoS) for a DDS entity.

Users have two options available to set the QoS for an entity or entities. They can define the QoS settings using an XML file, or they can use the Node.js DCPS APIs. Both of these options are explained.

If a QoS setting for an entity is not set using an xml file or the Node.js DCPS APIs, the defaults will be used. This allows a user the ability to override only those settings that require non-default values.

7.1. Setting QoS Using QoS Provider XML File

QoS for DDS entities can be set using XML files based on the XML schema file QoSProfile.xsd. These XML files contain one or more QoS profiles for DDS entities. OSPL includes an XSD (XML schema), that is located in $OSPL_HOME/etc/DDS_QoSProfile.xml. This can be used with XML schema core editors to help create valid XML files.

Sample QoS Profile XML files can be found in the examples directory. Typically you will place the qos files in a subdirectory of your Node.js application.

7.1.1. QoS Profile

A QoS profile consists of a name and optionally a base_name attribute. The base_name attribute allows a QoS or a profile to inherit values from another QoS or profile in the same file. The file contains QoS elements for one or more DDS entities.

A skeleton file without any QoS values is displayed below to show the structure of the file.

<dds xmlns="http://www.omg.org/dds/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="file:DDS_QoSProfile.xsd">
    <qos_profile name="DDS QoS Profile Name">
        <datareader_qos></datareader_qos>
        <datawriter_qos></datawriter_qos>
        <domainparticipant_qos></domainparticipant_qos>
        <subscriber_qos></subscriber_qos>
        <publisher_qos></publisher_qos>
        <topic_qos></topic_qos>
    </qos_profile>
</dds>

Example: Persistent QoS XML file

<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns="http://www.omg.org/dds/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="file:DDS_QoSProfile.xsd">
<qos_profile name="DDS PersistentQosProfile">
     <domainparticipant_qos>
          <user_data>
               <value></value>
          </user_data>
          <entity_factory>
               <autoenable_created_entities>true</autoenable_created_entities>
          </entity_factory>
     </domainparticipant_qos>
     <subscriber_qos name="subscriber1">
          <presentation>
               <access_scope>INSTANCE_PRESENTATION_QOS</access_scope>
               <coherent_access>true</coherent_access>
               <ordered_access>true</ordered_access>
          </presentation>
          <partition>
               <name>partition1</name>
          </partition>
          <group_data>
               <value></value>
          </group_data>
          <entity_factory>
               <autoenable_created_entities>true</autoenable_created_entities>
          </entity_factory>
     </subscriber_qos>
     <subscriber_qos name="subscriber2">
          <presentation>
               <access_scope>INSTANCE_PRESENTATION_QOS</access_scope>
               <coherent_access>false</coherent_access>
               <ordered_access>false</ordered_access>
          </presentation>
          <partition>
               <name></name>
          </partition>
          <group_data>
               <value></value>
          </group_data>
          <entity_factory>
               <autoenable_created_entities>true</autoenable_created_entities>
          </entity_factory>
     </subscriber_qos>
     <publisher_qos>
          <presentation>
               <access_scope>INSTANCE_PRESENTATION_QOS</access_scope>
               <coherent_access>true</coherent_access>
               <ordered_access>true</ordered_access>
          </presentation>
          <partition>
               <name>partition1</name>
          </partition>
          <group_data>
               <value></value>
          </group_data>
          <entity_factory>
               <autoenable_created_entities>true</autoenable_created_entities>
          </entity_factory>
     </publisher_qos>
     <datawriter_qos>
          <durability>
               <kind>PERSISTENT_DURABILITY_QOS</kind>
          </durability>
          <deadline>
               <period>
                    <sec>DURATION_INFINITE_SEC</sec>
                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
               </period>
          </deadline>
          <latency_budget>
               <duration>
                    <sec>0</sec>
                    <nanosec>0</nanosec>
               </duration>
          </latency_budget>
          <liveliness>
               <kind>AUTOMATIC_LIVELINESS_QOS</kind>
               <lease_duration>
                    <sec>DURATION_INFINITE_SEC</sec>
                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
               </lease_duration>
          </liveliness>
          <reliability>
               <kind>RELIABLE_RELIABILITY_QOS</kind>
               <max_blocking_time>
                    <sec>0</sec>
                    <nanosec>100000000</nanosec>
               </max_blocking_time>
         </reliability>
         <destination_order>
              <kind>BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS</kind>
          </destination_order>
          <history>
               <kind>KEEP_LAST_HISTORY_QOS</kind>
               <depth>100</depth>
          </history>
          <resource_limits>
               <max_samples>LENGTH_UNLIMITED</max_samples>
               <max_instances>LENGTH_UNLIMITED</max_instances>
               <max_samples_per_instance>LENGTH_UNLIMITED</max_samples_per_instance>
          </resource_limits>
          <transport_priority>
               <value>0</value>
          </transport_priority>
          <lifespan>
               <duration>
                    <sec>DURATION_INFINITE_SEC</sec>
                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
               </duration>
          </lifespan>
          <user_data>
               <value></value>
         </user_data>
         <ownership>
              <kind>SHARED_OWNERSHIP_QOS</kind>
          </ownership>
          <ownership_strength>
               <value>0</value>
          </ownership_strength>
          <writer_data_lifecycle>
               <autodispose_unregistered_instances>true</autodispose_unregistered_instances>
          </writer_data_lifecycle>
     </datawriter_qos>
     <datareader_qos>
          <durability>
              <kind>PERSISTENT_DURABILITY_QOS</kind>
          </durability>
          <deadline>
               <period>
                    <sec>DURATION_INFINITE_SEC</sec>
                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
               </period>
          </deadline>
          <latency_budget>
               <duration>
                    <sec>0</sec>
                    <nanosec>0</nanosec>
               </duration>
          </latency_budget>
          <liveliness>
               <kind>AUTOMATIC_LIVELINESS_QOS</kind>
               <lease_duration>
                    <sec>DURATION_INFINITE_SEC</sec>
                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
               </lease_duration>
          </liveliness>
          <reliability>
               <kind>BEST_EFFORT_RELIABILITY_QOS</kind>
               <max_blocking_time>
                    <sec>0</sec>
                    <nanosec>100000000</nanosec>
               </max_blocking_time>
          </reliability>
          <destination_order>
                <kind>BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS</kind>
          </destination_order>
          <history>
               <kind>KEEP_ALL_HISTORY_QOS</kind>
          </history>
          <resource_limits>
               <max_samples>LENGTH_UNLIMITED</max_samples>
               <max_instances>LENGTH_UNLIMITED</max_instances>
               <max_samples_per_instance>LENGTH_UNLIMITED</max_samples_per_instance>
          </resource_limits>
          <user_data>
               <value></value>
          </user_data>
          <ownership>
               <kind>SHARED_OWNERSHIP_QOS</kind>
          </ownership>
          <time_based_filter>
               <minimum_separation>
                    <sec>0</sec>
                    <nanosec>0</nanosec>
               </minimum_separation>
          </time_based_filter>
          <reader_data_lifecycle>
               <autopurge_nowriter_samples_delay>
                    <sec>DURATION_INFINITE_SEC</sec>
                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
               </autopurge_nowriter_samples_delay>
               <autopurge_disposed_samples_delay>
                    <sec>DURATION_INFINITE_SEC</sec>
                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
               </autopurge_disposed_samples_delay>
          </reader_data_lifecycle>
     </datareader_qos>
     <topic_qos>
          <topic_data>
               <value></value>
          </topic_data>
          <durability>
               <kind>PERSISTENT_DURABILITY_QOS</kind>
          </durability>
          <durability_service>
               <service_cleanup_delay>
                    <sec>3600</sec>
                    <nanosec>0</nanosec>
               </service_cleanup_delay>
               <history_kind>KEEP_LAST_HISTORY_QOS</history_kind>
               <history_depth>100</history_depth>
               <max_samples>8192</max_samples>
               <max_instances>4196</max_instances>
               <max_samples_per_instance>8192</max_samples_per_instance>
          </durability_service>
          <deadline>
               <period>
                    <sec>DURATION_INFINITE_SEC</sec>
                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
               </period>
          </deadline>
          <latency_budget>
               <duration>
                    <sec>0</sec>
                    <nanosec>0</nanosec>
               </duration>
          </latency_budget>
          <liveliness>
               <kind>AUTOMATIC_LIVELINESS_QOS</kind>
               <lease_duration>
                    <sec>DURATION_INFINITE_SEC</sec>
                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
               </lease_duration>
          </liveliness>
          <reliability>
               <kind>BEST_EFFORT_RELIABILITY_QOS</kind>
               <max_blocking_time>
                    <sec>0</sec>
                    <nanosec>100000000</nanosec>
                    </max_blocking_time>
          </reliability>
          <destination_order>
               <kind>BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS</kind>
          </destination_order>
          <history>
               <kind>KEEP_LAST_HISTORY_QOS</kind>
               <depth>1</depth>
          </history>
              <resource_limits>
               <max_samples>LENGTH_UNLIMITED</max_samples>
               <max_instances>LENGTH_UNLIMITED</max_instances>
               <max_samples_per_instance>LENGTH_UNLIMITED</max_samples_per_instance>
          </resource_limits>
          <transport_priority>
               <value>0</value>
          </transport_priority>
          <lifespan>
               <duration>
                    <sec>DURATION_INFINITE_SEC</sec>
                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
              </duration>
          </lifespan>
          <ownership>
               <kind>SHARED_OWNERSHIP_QOS</kind>
          </ownership>
     </topic_qos>
</qos_profile>
</dds>

7.1.2. Applying QoS Profile

To set the QoS profile for a DDS entity using the Node.js DCPS API and an XML file, the user specifies the qos file URI or file path and the QoS profile name as parameters.

Example: Using QoSProvider

const dds = require('vortexdds');
const path = require('path');

const QOS_XML_PATH = __dirname + path.sep + 'DDS_Get_Set_QoS.xml';
const QOS_PROFILE = 'DDS GetSetQosProfile';
const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT;

//...

async function setup(){

    let participant = null;
    let qp = null;
    try {
        // create a qos provider using qos xml file
        qp = new dds.QoSProvider(QOS_XML_PATH, QOS_PROFILE);

        // get participant qos from qos provider and create a participant
        const pqos = qp.getParticipantQos();

        participant = new dds.Participant(DOMAIN_ID, pqos);

        // get publisher qos from qos provider
        const pubqos = qp.getPublisherQos();

        // get publisher qos policies
        const pubScope = pubqos.presentation;
        const publisher = participant.createPublisher(pubqos);

        //...

    } finally {
        console.log('=== Cleanup resources');
        if (qp !== null){
           qp.delete();
        }
        if (participant !== null){
          participant.delete().catch((error) => {
            console.log('Error cleaning up resources: '
              + error.message);
          });
        }
    }
}

7.2. Setting QoS Using Node.js DCPS API Classes

QoS settings can also be set by using the Node.js classes alone. (No XML files required.)

Example: Create Reader Using QoS APIS

const dds = require('vortexdds');

//...

function createReader(subscriber, topic){

    // get the default reader qos
    const rqos = dds.QoS.readerDefault();

    // modify the reader qos policies
    rqos.partition = {names: 'partition1'};
    rqos.timebasedFilter = {minimumSeparation: 60000};
    rqos.readerDataLifecycle = {
        autopurgeNoWriterSamples: 100,
        autopurgeDisposedSamplesDelay: 500,
    };

    // create a reader with qos
    const reader = subscriber.createReader(topic, rqos);

    //...
}