4. What’s New in 7.4.0

This section describes what’s new in the Core Libraries compared to release 7.3.0 LTS.

RTI® Connext® 7.4.0 is an early access release. See the Connext Releases page on the RTI website for more information on RTI’s software release model.

For what’s new and fixed in other products in the Connext suite, see those products’ release notes on the RTI Community Portal or in your installation. Or start with the RTI Connext What’s New for a launchpad to all products.

Note

For backward compatibility information between 7.4.0 and previous releases, see the Migration Guide on the RTI Community Portal.

4.1. Set up reliable communications for fragmented data more easily and with better performance, by removing asynchronous publishing requirement

In earlier releases of Connext, if your data exceeded the transport’s configured maximum message size (message_size_max) and required fragmentation, and your DataWriter was communicating with a reliable DataReader, you had to manually enable asynchronous publishing on the DataWriter. If not enabled, Connext would display a warning, and communication would not occur:

“WARNING Max serialized size of type ‘your_type’ (your_type_max_serialized_size) exceeds the transport’s message size max (your_message_size_max_configuration). Consider using asynchronous publishing or increasing message size max otherwise samples with a serialized size larger than ‘your_message_size_max_configuration’ will not be able to be sent.”

From Connext release 7.4.0 onward, sending fragmented data reliably with synchronous DataWriters has become possible. This functionality, previously available only for best-effort communications, has now been extended to support reliable endpoints as well.

This enhancement not only simplifies your workflow by removing the need to pre-configure asynchronous publishing based on data fragmentation requirements, but also leverages the generally lower latency of synchronous DataWriters.

As part of this work, the following RtpsReliableWriterProtocol_t QoS policy settings, which previously applied only to DDS samples, now apply to both DDS samples and DDS fragments:

  • min_nack_response_delay and max_nack_response_delay set the boundaries of a time interval within which missing samples must be repaired. This interval allows for any additional NACKs (for missing samples) and NACK_FRAGs (for missing data fragments) that are received during that time to be coalesced and responded to all at once instead of individually.

  • nack_suppression_duration specifies a duration within which subsequent duplicate NACKs or NACK_FRAGs are disregarded. If a duplicate NACK or NACK_FRAG is received within this duration, it will not trigger another repair process.

  • max_bytes_per_nack_response allows for basic flow control of repair data by limiting the number of bytes that will be sent in response to a NACK or NACK_FRAG. A DataWriter will repair the missing samples until this limit is reached, always repairing at least one sample. The samples that were not repaired will be repaired in the next received NACK or NACK_FRAG.

The enhancement to these settings means you can now shape the traffic of data fragment repairs without relying on a flow controller (asynchronous publishing) and still benefit from the advantages of using synchronous publishing.

For background information on these topics, see Sending Large Data, ASYNCHRONOUS_PUBLISHER QosPolicy (DDS Extension), and Data Fragmentation in the RTI Connext Core Libraries User’s Manual.

4.2. Modern C++ RPC API now fully productized and supported

This release promotes the RPC C++ API from experimental to production-ready. It includes several improvements to the RPC and Request-Reply Modern C++ APIs that align the API with the future update of the OMG DDS-RPC standard and provide several new features, most notably, an enhanced service discovery protocol.

The enhanced service discovery protocol allows a Client (or a Requester) to reliably discover a Service (or a Replier) before making a call:

  • Clients and Requesters can call a new method, wait_for_service(), to ensure that a service has been discovered.

  • Clients and Requesters will fail immediately when making a request if no service has been discovered. This behavior can be disabled on the Requester with the new RequesterParams option, require_matching_service_on_send_request, for interoperability with request-reply APIs in other languages and previous versions of the C++ API.

  • A Service or a Replier will only pass requests to the application layer when it can ensure that the reply can be delivered. This solves a previous race condition that could cause some initial replies for a Client or Requester to be lost.

Other changes include:

  • Changes the translation of service interfaces to topic-types to align with a future update of the OMG RPC-DDS standard.

  • Allows for the mutability of RPC operations by supporting the @final and @mutable annotations on a per-operation basis.

For example, the following interfaces are compatible. A Foo client can call my_method on a Bar service, and the other way around (as long as they use the same service name):

@service("DDS")
interface Foo {
       @mutable
       long my_methodop(in short s, out double d);
};

@service("DDS")
interface Bar {
     @mutable
     void my_method(in short s, out double d, in long l);
};
  • Allows the propagation of built-in exceptions: dds::rpc::RemoteUnsupportedOperationError, dds::rpc::RemoteInvalidArgumentError, dds::rpc::RemoteOutOfResourcesError, dds::rpc::RemoteUnknownOperationError, dds::rpc::RemoteUnknownExceptionError, in addition to the already-supported user-defined exceptions. These built-in exceptions can be explicitly thrown by the service implementation. Additionally, dds::rpc::RemoteUnknownOperationError and dds::rpc::RemoteUnknownExceptionError are reported when the client calls an unknown operation in the service or the service implementation throws an unknown exception, respectively.

  • Allows setting wire compatibility with rti::config::compliance::RpcMask so that the PID_RELATED_SAMPLE_IDENTITY RTPS parameter is set to its standard value. By default, it continues to be set to a non-standard value for backward compatibility with previous Connext versions.

Note: The RPC Python API continues to be experimental, but will be production-ready in an upcoming release. It incorporates most of these updates, except that it doesn’t yet provide the wait_for_service() API and doesn’t fail when sending a Request before discovering a service. It doesn’t provide the option to change the PID_RELATED_SAMPLE_IDENTITY parameter, either. (The Request-Reply Python API is production-ready.)

See Request-Reply Exchanges and Remote Procedure Calls (RPC) in the RTI Connext Core Libraries User’s Manual for information on these APIs.

4.3. Discover relevant QoS more easily through categorizations added to API Reference HTML documentation

Connext Qualities of Service (QoS) policies and fields have been grouped into categories.

../_images/qos_categories_apiref.png

The categories are also listed with each QoS field’s documentation in the API HTML Documentation.

../_images/qos_categories_labels.png

These categories can help you discover which QoS may be relevant or related to a desired functionality or feature. For example, if you are interested in Sending Large Data, then looking at any QoS in that category will be helpful. The different functional categories are listed in the API HTML Documentation under Modules > RTI Connext DDS API Reference > Infrastructure > QoS > QoS Categories > Functional Categories. For example, see Functional Categories in the Modern C++ API Reference.

Some categories are not necessarily related to achieving a specific functionality, but are characteristics of the QoS – for example, if the QoS are mutable or not, or if they apply per-instance. These categories are listed under the following headings in the API Reference:

  • Modules > RTI Connext DDS API Reference > Infrastructure > QoS > QoS Categories > QoS Mutability

  • Modules > RTI Connext DDS API Reference > Infrastructure > QoS > QoS Categories > Other QoS Attributes

4.4. Easier QoS configuration for Request-Reply and RPC with new built-in QoS profile

This release includes a new built-in profile, BuiltinQosLib::Pattern.RPC that can be used to obtain the default values used to create the DataReaders and DataWriters within a Requester, Replier, RPC Client, or RPC Service.

You can use this profile as the base profile in your XML configuration. Find an example that uses the built-in profile in the GitHub Examples repository: https://github.com/rticommunity/rticonnextdds-examples/blob/master/examples/connext_dds/remote_procedure_call/c%2B%2B11/USER_QOS_PROFILES.xml.

Our you can use the profile in code. For example:

In C++:

auto qos_provider = dds::core::QosProvider::Default();
auto rpc_reader_qos = qos_provider.datareader_qos(
    rti::core::builtin_profiles::qos_lib::pattern_rpc());
auto rpc_writer_qos = qos_provider.datawriter_qos(
    rti::core::builtin_profiles::qos_lib::pattern_rpc());

// modify rpc_reader_qos/rpc_writer_qos...

rti::request::Requester<Foo, Bar> requester(
            rti::request::RequesterParams(participant)
                    .service_name("my service")
                    .datareader_qos(rpc_reader_qos)
                    .datawriter_qos(rpc_writer_qos);

In Python:

import rti.rpc as rpc
import rti.connextdds as dds

rpc_reader_qos = dds.QosProvider.default.datareader_qos_from_profile(
    dds.BuiltinProfiles.pattern_rpc
)
rpc_writer_qos = dds.QosProvider.default.datawriter_qos_from_profile(
    dds.BuiltinProfiles.pattern_rpc
)

# modify rpc_reader_qos/rpc_writer_qos...

requester = rpc.Requester(
    Foo,
    Bar,
    participant,
    "my service",
    datareader_qos=rpc_reader_qos,
    datawriter_qos=rpc_writer_qos,
)

4.5. Write Python applications faster with reactive subscriptions

This release adds a new feature to the Connext Python API that allows subscribing to a topic by simply decorating a function that receives the updates for that topic.

For example, the following is a full application that subscribes to two topics, “Sensor Temperature” and “Alerts,” and prints the data received for each topic:

import rti.asyncio
from my_types import Temperature, Alert

app = rti.asyncio.Application()

@app.subscribe("Sensor Temperature")
async def on_sensor_temperature(data: Temperature):
    print("Received Sensor Temperature:", data)

@app.subscribe("Alerts")
async def on_alert(data: Alert):
    print("Received Alert:", data)

if __name__ == "__main__":
    rti.asyncio.run(app.run(domain_id=0))

rti.asyncio.Application is a new class that creates a Topic and a DataReader for any async function decorated with its subscribe decorator, and passes all data updates for that topic to the function. The topic type is inferred from the function’s argument type annotation.

This feature allows quickly writing Python applications that subscribe to one or more topics.

For more information, see the Python API Documentation.

4.6. New Ping built-in type helps debug and prototype with the Python API

This release adds a new built-in type to the Python API, rti.types.builtin.PingType. This is the type that the rtiddsping command-line utility publishes and subscribes to and consists of a single 32-bit integer. This type helps you quickly interact with rtiddsping from a Python application to debug or prototype without having to define the type yourself. For example, the following Python script prints the data published by rtiddsping:

from rti.types.builtin import PingType
import rti.asyncio

app = rti.asyncio.Application()

@app.subscribe("PingTopic")
async def on_ping(ping: PingType):
    print("Received ping:", ping.number)

rti.asyncio.run(app.run(domain_id=0))

(This snippet uses the rti.asyncio.Application utility for simplicity, which is also new in this release.)

And you can publish that topic by just running rtiddsping with no arguments:

$ rtiddsping

For more about the built-in types in the Python API, see rti.types.builtin in the Python API reference.

4.7. DDS Spy now prints full timestamps (with date and fractions of a second) and epoch timestamps

In previous releases, rtiddsspy displayed timestamps in the hh:mm:ss format, which didn’t include the date or fractions of a second.

This release adds a new option, -timeFormat SHORT | FULL | EPOCH:

  • -timeFormat SHORT is the default and prints in hh:mm:ss format.

  • -timeFormat FULL adds the date and fractions of a second: yy:mm:dd hh:mm:ss.s.

  • -timeFormat EPOCH displays the time as the number of seconds since the Unix epoch.

For example:

$ rtiddsspy -printSample COMPACT -timeFormat FULL

2024-05-24 01:35:35.154618 New writer        from 10.0.0.225      : topic="PingTopic" type="PingType"
2024-05-24 01:35:35.154836 New data          from 10.0.0.225      : topic="PingTopic" type="PingType" sample={"number":0}
2024-05-24 01:35:36.159999 New data          from 10.0.0.225      : topic="PingTopic" type="PingType" sample={"number":1}

See the DDS Spy User’s Manual for more information.

4.8. New DynamicData APIs get and set a union’s discriminator value

Two new DynamicData APIs have been added that allow getting and setting a union’s discriminator value: DynamicData::get_discriminator() and DynamicData::set_discriminator().

Previously, passing index 0 to the DynamicData::get_member_info_by_index() API returned the discriminator value for a union in the DynamicDataMemberInfo::member_id field. This behavior has been deprecated and the DynamicData::get_discriminator() API should be used instead.

The DynamicData::set_<type>() APIs used to be the only way to set the discriminator value, by providing the desired discriminator value as the member_id. Now, the discriminator value can also be set using the DynamicData::set_discriminator() API.

See Accessing the Discriminator Value in a Union in the Core Libraries User’s Manual and the API documentation for more information about these APIs and examples of how to use them.

4.9. Deprecations and Removals

This section describes items that are deprecated or removed in 7.4.0, compared to 7.3.0 LTS.

Deprecated means that the item is still supported in this release, but will be removed in a future release. Removed means that the item is discontinued or no longer supported.

Any deprecations or removals noted in RTI’s documentation serve as notice under the Real-Time Innovations, Inc., Maintenance Policy #4220 and/or any other agreements by and between RTI and customer regarding maintenance and support of RTI’s software. RTI’s current standard terms and support and maintenance policies are available at https://www.rti.com/terms.

4.9.1. Simplify QoS configuration by deprecating unnecessary or rarely used QoS settings and policies

As part of the effort to simplify Quality of Service (QoS) configuration in Connext, this release has deprecated a number of QoS settings and policies because their use cases are narrow or they are seldom used. Although still available, these QoS may be removed in a future release, handled by new functionality, or hidden. These QoS are marked as deprecated in the API Reference and RTI Connext Core Libraries User’s Manual.

To see the full list of deprecated QoS settings, see the API Reference HTML documentation under Modules > RTI Connext DDS API Reference > Infrastructure > QoS > QoS Categories > Deprecated QoS. For example, see Deprecated QoS in the Modern C++ API Reference.

4.9.2. dds.sample_assignability.accept_unknown_enum_value and dds.sample_assignability.accept_unknown_union_discriminator properties deprecated

As described in OMG Specification Compliance, the properties dds.sample_assignability.accept_unknown_enum_value and dds.sample_assignability.accept_unknown_union_discriminator have been deprecated and replaced with Extensible Types compliance mask bits. See Extensible Types Compliance Mask in the Core Libraries Extensible Types Guide for more information.

If you are currently using the properties, see the 7.4.0 Migration Guide on the RTI Community Portal for information on configuring their behavior using the Extensible Types compliance mask bits.

4.9.3. dds.participant.use_45d_compatible_alignment_enforcement property deprecated

The dds.participant.use_45d_compatible_alignment_enforcement property is deprecated in this release. It is still functional in this release and can be used when interoperating with Connext 4.5d or earlier. It should not be used when your system does not include any legacy (earlier than 4.5d) Connext-based applications.

4.9.4. EXCLUSIVE_AREA QoS policy removed

The EXCLUSIVE_AREA QoS policy was deprecated in release 6.1.1. In release 7.3.0, it was announced to no longer be supported, and its documentation was removed. In this release, it is fully removed (all user-accessible code associated with the QoS has been removed). This removal only affects the EXCLUSIVE_AREA QoS policy (the ability to set use_shared_exclusive_area).