4. What’s New in 7.3.0 LTS

This section describes what’s new in the Core Libraries compared to release 7.2.0. For information on new features in releases 7.0.0, 7.1.0, and 7.2.0, which are all also part of 7.3.0 LTS, see Previous Releases, in the RTI Connext What’s New.

For what’s new and fixed in other products in the Connext suite, see those products’ release notes on https://community.rti.com/documentation 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.3.0 LTS and previous releases, see the Migration Guide on the RTI Community Portal (https://community.rti.com/documentation).

4.1. Sending and Receiving Data

4.1.1. Type evolution now allowed with Zero Copy transfer over shared memory when using FlatData types

Previously, type coercion was not permitted for any topics using Zero Copy regardless of the language binding, which means that you could not evolve the types. If you had set reader_qos.type_consistency.kind to AUTO_TYPE_COERCION for a Zero Copy DataReader, Connext translated this value to DISALLOW_TYPE_COERCION. Setting reader_qos.type_consistency.kind to ALLOW_TYPE_COERCION resulted in an error when creating a Zero Copy DataReader.

In this release, this restriction no longer applies to topics using Zero Copy when the underlying type is annotated as a FlatData type, allowing type evolution while using Zero Copy.

See Other Considerations, in Zero Copy Transfer Over Shared Memory, in the RTI Connext Core Libraries User’s Manual, for more information.

4.1.2. Simpler DataReader and DataWriter constructors (Python, Modern C++ APIs)

Many applications don’t need an explicit Subscriber or Publisher if they don’t require features like ordered access or partitions. Starting with this release, in the Python and Modern C++ APIs, the subscriber argument for the DataReader constructors and the publisher argument to the DataWriter constructors are optional. When not specified, the implicit subscriber and the implicit publisher are used, respectively.

For example, this new way to create a DataReader is available:

In Python:

reader = dds.DataReader(topic, Foo)

In modern C++:

DataReader<Foo> reader(topic);

These are equivalent to the following:

In Python:

reader = dds.DataReader(topic.participant.implicit_publisher, topic, Foo)

In modern C++:

DataReader<Foo> reader(rti::sub::implicit_subscriber(topic.participant()), topic);

Note that other language APIs that use a factory pattern are unchanged, since the DomainParticipant provides create_datareader() and create_datawriter() methods that don’t require a Subscriber or Publisher.

4.1.3. Topic constructors now receive std::string_view arguments

When an application using the Modern C++ API is compiled with support for C++17 or higher, the Topic constructors now receive a std::string_view argument instead of a std::string. Many applications define their topic names as string constants in the application or in IDL. The new IDL4-C++ mapping translates IDL string constants to std::string_view in C++. By declaring a std::string_view argument, the Topic constructors now accept any type of string (std::string, std::string_view, char*, etc.).

4.1.4. Directly get duration in nanoseconds, instead of calculating it, using new to_nanosec function in Duration class

A new function, to_nanosec, is now available in the Duration class to get the number of nanoseconds equivalent to the time expressed in a Duration object. This new functionality enables you to get a duration value directly in nanoseconds. You no longer need to calculate nanoseconds from the output of other functions (like the output of to_microsec).

4.1.5. JSON now a fully supported data format, enabling easier integration of Connext with other technologies

Connext already provided to_string APIs that allowed converting a data sample into a JSON string (and other formats). This release adds from_string APIs that allow creating a data sample from a JSON string representation.

For example, given an IDL type Point, defined as follows:

struct Point {
    int32 x;
    int32 y;
};

Connext applications can now create and publish a Point instance from a JSON string such as {"x": 1, "y": 2}.

The following APIs have been added.

  • In the Modern C++ API: rti::topic::from_string

Point p = rti::topic::from_string<Point>("{\"x\": 10, \"y\": 20}");
  • In the Python API: TypeSupport.from_string and, for convenience, TypeSupport.from_json as well as TypeSupport.to_json:

import rti.types as idl

point_support = idl.get_type_support(Point)
point = point_support.from_json(r'{"x": 10, "y": 20}')
  • In the C# API, <Type>Support.FromString:

Point p = PointSupport.Instance.FromString("{\"x\": 10, \"y\": 20}")
  • In the Java API, <Type>TypeSupport.data_from_string:

Point p = PointTypeSupport.get_instance().data_from_string("{\"x\": 10, \"y\": 20}")

It’s also possible to convert from DynamicData samples to JSON strings; the class DynamicData includes a new from_string method.

After obtaining the Point data sample, you can publish it using a DataWriter for Point (or DynamicData) as usual. A DataReader can receive the Point sample and convert it to JSON using the to_string APIs.

(Note that in the C and Traditional C++ APIs, only DynamicData provides this functionality.)

4.2. Performance

4.2.1. Skip deserialization in DynamicData for efficient data handling, using new property

By default, a DynamicData object stores its contents in an implementation-specific representation that allows you to get and set fields by name or ID. For this to work, Connext must deserialize the sample; however, there are cases where you do not need to mutate or access the data. One such case is when you are storing the data for later. Another is when you are bridging samples to another domain and do not need to inspect the data. For enhanced performance in these types of cases, you can now skip deserialization.

The property skip_deserialization can be set to true to skip the automatic deserialization of DynamicData objects. To determine if a sample is in this internal format, use the DDS_DynamicData_is_cdr functions. Additionally, some function names have been changed to be consistent with this new functionality. DDS_DynamicData_set_and_lock_buffer has been changed to DDS_DynamicData_set_cdr_buffer. DDS_DynamicData_get_storage_buffer has been renamed DDS_DynamicData_get_cdr_buffer. Both of these functions can be used to work with the data that has not been deserialized yet. For more information about them, see the language-specific API Reference documentation. Also find an example here: https://github.com/rticommunity/rticonnextdds-examples/tree/master/examples/connext_dds/dynamic_data_skip_serialization.

4.2.2. Compression level applied to built-in Instance State Consistency DataWriter reduced, speeding up response time and reducing CPU usage

Instance state consistency is achieved through the use of a built-in DataWriter that sends information regarding instances to a built-in DataReader. The samples sent by this DataWriter can be very large, and so compression is applied to this channel. The compression level was previously DDS_COMPRESSION_LEVEL_BEST_COMPRESSION (slowest, but best, compression). This compression level has been updated to DDS_COMPRESSION_LEVEL_BEST_SPEED. See Data Compression in the RTI Connext Core Libraries User’s Manual for more information on these compression levels. (Note that the builtin DataWriter/DataReader for instance state consistency does not use the same compression_settings defaults as described in Data Compression. It uses ZLIB, BEST_SPEED, and 1024 as the defaults.)

4.2.3. Performance improvement for durable writer history and Persistence Service with high late-joiner activity

You may have experienced performance degradation while using durable writer history and Persistence Service, particularly in scenarios with high late-joiner activity. This problem was due to the durable DataWriter not caching repair samples in the durable writer history, leading to excessive database queries from the different late-joiners. Connext now caches repair samples if the cache has sufficient capacity (writer_qos.resource_limits.max_samples is less than or equal to writer_qos.durability.storage_settings.writer_instance_cache_allocation.max_count).

4.2.4. Performance improvement in large systems using SHMEM transport

This release introduces changes to the SHMEM transport that may lead to application performance improvements in systems that create many DomainParticipants on the same host that communicate with each other over SHMEM. Before, all DataWriter write operations in a DomainParticipant were serialized at the transport level, regardless of whether the application employed distinct Publishers for different DataWriters. With this improvement, a DomainParticipant can now perform concurrent writes to other DomainParticipants in the system.

4.2.5. More efficient use of network and CPU resources, through support for multiple instances of a UDPv4/UDPv6 transport in a single DomainParticipant

By default, it is not possible to have multiple instances of the UDPv4 or UDPv6 transport in the same DomainParticipant, because all instances will try to bind to the same UDP port(s) for receiving data. This release adds the ability to instantiate multiple instances of the UDPv4 and UDPv6 transport within a single DomainParticipant, if desired, using two new properties, dds.transport.UDPv4.builtin.port_offset and dds.transport.UDPv6.builtin.port_offset. This enhancement enables more efficient use of network and CPU resources, which is particularly beneficial when Connext applications are operating across various subnets.

With the new properties, you can specify an offset that will be added to the RTPS port(s) to determine the UDP port(s) to bind to. In this way, you can have multiple instances of the UDPv4/UDPv6 transport in the same DomainParticipant, if each instance uses different offsets. For more information, see Instantiating Multiple Instances of UDPv4/UDPv6 Transports in the RTI Connext Core Libraries User’s Manual.

FigureTransportSubnets

4.3. Debugging and Logging

4.3.1. Set exactly the metrics you want to collect for Observability Framework, using new setting in MONITORING QoS policy

Previously, every observable resource (DomainParticipant, Publisher, DataReader, etc.) was, by default, subscribed to all the available metrics for that resource when it was registered. However, you may not be interested in collecting all of those metrics.

Starting in release 7.3.0, you can now configure the initial set of metrics a resource will be subscribed to upon registration, using the MonitoringQosPolicy. More precisely, you can use the <metrics> tag under <participant_factory_qos>/<monitoring> in XML or the field telemetry_data.metrics in the MONITORING QosPolicy documentation.

Note: Starting in this release, by default no metrics will be enabled for any resource unless you specify them in the metrics QoS setting. However, if you choose to enable monitoring by using the built-in snippet Feature.Monitoring2.Enable, all available metrics will be enabled for all resources.

4.3.2. Better understand port collision warnings through improved logging

If enabled, some benign warning level log messages are printed during Automatic Participant ID Selection (see Choosing Participant IDs in the RTI Connext Core libraries User’s Manual for more information) because of an expected port collision. Before 7.3.0, these log messages were shown as follows:

WARNING [0x0101B4A0,0x30B6995B,0x3CA153D8:0x000001C1{Domain=0}|CREATE DP|ENABLE|LC:DISC]NDDS_Transport_UDPv4_Socket_bind_with_ip:0X1CF2 in use
WARNING [0x0101B4A0,0x30B6995B,0x3CA153D8:0x000001C1{Domain=0}|CREATE DP|ENABLE|LC:DISC]NDDS_Transport_UDPv4_SocketFactory_create_receive_socket:invalid port 7410
WARNING [0x0101B4A0,0x30B6995B,0x3CA153D8:0x000001C1{Domain=0}|CREATE DP|ENABLE|LC:DISC]NDDS_Transport_UDP_create_recvresource_rrEA:!create socket

From 7.3.0, these log messages have been improved to clarify that they are benign, adding the AUTO ID COMPUTE activity context and a last log message clarifying that we are trying the next port:

WARNING [0x01018B7A,0x24B6E2C3,0xC6FB093A:0x000001C1{Domain=0}|CREATE DP|ENABLE|AUTO ID COMPUTE|LC:Discovery]NDDS_Transport_UDPv4_Socket_bind_with_ip:BIND FAILURE | Port 7410 in use
WARNING [0x01018B7A,0x24B6E2C3,0xC6FB093A:0x000001C1{Domain=0}|CREATE DP|ENABLE|AUTO ID COMPUTE|LC:Discovery]NDDS_Transport_UDPv4_SocketFactory_create_receive_socket:BIND FAILURE | Invalid port 7410
WARNING [0x01018B7A,0x24B6E2C3,0xC6FB093A:0x000001C1{Domain=0}|CREATE DP|ENABLE|AUTO ID COMPUTE|LC:Discovery]NDDS_Transport_UDP_create_recvresource_rrEA:CREATION FAILURE | Socket
WARNING [0x01018B7A,0x24B6E2C3,0xC6FB093A:0x000001C1{Domain=0}|CREATE DP|ENABLE|AUTO ID COMPUTE|LC:Discovery]DDS_DomainParticipantPresentation_reserve_participant_index_entryports:Trying next port...

4.3.3. New log message warning if sample’s serialized size exceeds MTU and risks not being sent

A new warning level log message has been added that lets you know when you have created a type whose serialized size is greater than the smallest message_size_max across all transports. This message is not logged if asynchronous publishing is used or if the type contains unbounded members. If you receive this message and you do not update the message_size_max, the samples will not be able to be sent. See Large Data Fragmentation in the RTI Connext Core Libraries User’s Manual for more information on message_size_max.

4.3.4. Overly long activity context section of log message now truncated instead of generating additional log messages

Previously, if the activity context section of a log message was too long to fit in the log message, the following log message would be printed:

There was a problem while logging the following LOCAL message through the Connext built-in logging system. It will be logged only to STDOUT: RTIOsapiActivityContext_getString:!context maxEntryCount has been reached.

This log message has been removed. The activity context section of the log message will now be truncated, and the last 14 characters will be replaced with (msgTruncated). An example of a truncated log message is below:

LOCAL [0xDFCD91E1,0x68683864,0xB9B0569F:0x000001C1{Domain=0}|CREATE DP|ENABLE|:0x00000188{Entity=Pu,Domain=0}|CREATE DW WITH TOPIC DCPSParticipantVolatileMessageSecure|:0xFF0202C3{Entity=DW,Topic=DCPSParticipantVolatileMessageSecure,Type=ParticipantGenericMessage,Domain=0}|ENABLE|:0x000001C1{Domain=0}|ASSERT REMOTE DW|:0xFF0202C4{Entity=DR,Topic=DCPSParticipantVolatileMessageSecure,Type=ParticipantGenericMessage,Domain=0}|LINK 0xDFCD91E1,0x68683864,0xB9B0569F:0xFF0202C3{Type=ParticipantGenericMessag(msgTruncated)|LC:DISC,SEC]RTI_Security_Cryptography_registerEndpoint:{"DDS:Security:LogTopicV2":{"f":"10","s":"3","t":{"s":"1698688649","n":"612150999"},"h":"RTI-10827.local","i":"0.0.0.0","a":"RTI Secure DDS Application","p":"38892","k":"security","x":[{"DDS":[{"domain_id":"0"},{"guid":"dfcd91e1.68683864.b9b0569f.1c1"},{"plugin_class":"Cryptography"},{"plugin_method":"RTI_Security_Cryptography_registerEndpoint"}]}],"m":"successfully registered endpoint"}}

4.3.5. Set finer-grained time values for logging properties that take a duration

The following properties now accept values smaller than one second:

  • dds.participant.logging.time_based_logging.event.timeout

  • dds.participant.logging.time_based_logging.send.timeout

  • dds.participant.logging.time_based_logging.process_received_message.timeout

  • dds.participant.logging.time_based_logging.authentication.timeout

The properties still accept a single number, which represents the threshold in seconds, but they also accept a value in the form of #s#ms#us#ns so that seconds, milliseconds, microseconds, and nanoseconds can be specified as part of the threshold. The format allows any of the values to be provided, or not, in any order. Some examples of accepted values are:

  • 2

  • 1s500ms

  • 250000000ns

See Setting Warnings for Operation Delays in the RTI Connext Core Libraries User’s Manual.

4.3.6. Log messages for use by Logger Device contain further useful information: timestamp, source (facility), and message ID

This feature was introduced in 7.1.0, but not documented at that time.

The LogMessage data type now contains three new fields:

  • facility: The Syslog facility associated with the log message. In the Syslog Protocol, the facility is a numerical code that represents the machine process that created a Syslog event. Connext uses the facility to represent the source of a given log message. Valid values are: 23 (middleware), 10 (security_event), 22 (service), and 1 (user).

  • message_id: A numeric code that identifies a specific log message. Two log messages that have the same message_id will have a similar structure. For example, the message_id of both “ERROR: Failed to get DataWriterQos” and “ERROR: Failed to get TopicName” is associated with the get failure.

  • timestamp: A Duration structure referring to the time when the message was logged.

These fields are available in your application through the use of a Logger Device. See Customizing the Handling of Generated Log Messages. The new fields are documented in the API Reference HTML documentation (for example, here in the Modern C++ API Reference).

4.3.7. New logging APIs provide ability to emit custom log messages in Connext applications

The new logging APIs provide the ability to emit custom log messages in Connext applications. This feature will provide more control over the logging process, capture specific application events, and provide deeper insights into the behavior of the application. These new APIs are flexible and allow developers to include relevant information about application-specific events, errors, warnings, or any other important data that requires logging. The new APIs support the use of NDDS_Config_SyslogLevel severity levels and provide an API function in the NDDS_Config_Logger for each level. A new log category NDDS_CONFIG_LOG_CATEGORY_USER has been added to NDDS_Config_LogCategory to accommodate this new category of log messages.

4.3.8. New log warnings when SPDP and SPDP2 participants cannot communicate

DomainParticipants using different discovery protocols (SPDP vs SPDP2) cannot communicate. Now, in this release, when DomainParticipants using different discovery protocols detect each other, a log message is generated at the warning level. By default, this logging of mismatch warnings is enabled. You can disable or enable this log message using the boolean property dds.participant.discovery_config.log_discovery_mismatch. The messages generated by this condition are:

SPDP2 participant received message from SPDP participant. These two participants will not communicate.

SPDP participant received message from SPDP2 participant. These two participants will not communicate.

4.4. DDS Ping and DDS Spy

4.4.1. New option in DDS Ping and DDS Spy to configure Builtin Discovery Plugins

There is a new option, -discoveryPlugins, in DDS Ping and DDS Spy to support configuring the Builtin Discovery Plugins. This new option accepts two values:

  • SDP: Simple Participant Discovery Protocol and Simple Endpoint Discovery Protocol.

  • SDP2: Simple Participant Discovery Protocol 2.0 (SPDP2) and Simple Endpoint Discovery Protocol.

The -discoveryPlugins option enables you to configure the discovery mechanism (to SDP or SDP2) more easily without the need to load an XML file with that configuration (and then specify that configuration using the -qosProfile option).

See the RTI DDS Spy User’s Manual and the RTI DDS Ping User’s Manual.

4.4.2. New option in DDS Ping and DDS Spy to configure participant partitions

There is a new option, -participantPartition, in DDS Ping and DDS Spy to support configuring DomainParticipant partitions. Also, the existing, partition option in DDS Spy has been renamed to -subscriberPartition.

4.5. Miscellaneous

4.5.1. Python API supports latest version, Python 3.12

This release adds support for the Connext Python API on Python 3.12. The API now runs on versions 3.6 to 3.12.

4.5.2. Determine a dynamic type’s minimum serialized sample size using new cdr_serialized_sample_min_size

The Python API now exposes a function, cdr_serialized_sample_min_size, for finding the minimum size in bytes that a Dynamic Type can be. This function can be used to help determine the minimum resource limits required. For example, along with the maximum serialized size, you can now determine how much disk space or RAM your system will need in order to perform a task. The maximum size was already available.

4.5.3. Validate a license using a shared library call

This release adds the option for a Connext application to validate an activation string (license) provided through a shared library call that you can implement. This feature removes the need for a license file on the system where Connext runs, and supports use cases where applications retrieve activation strings from a license server. See License Management in the RTI Connext Installation Guide for details.

4.5.4. Micro Compatibility Builtin Profile updated to not send serialized types

The Generic.ConnextMicroCompatibility builtin QoS profile has been updated to set the type_code_max_serialized_length and type_object_max_serialized_length resource limits to 0, which disables sending serialized types as part of endpoint discovery. Connext Micro does not use serialized type information for endpoint discovery, so sending the type from a Connext Professional application to a Connext Micro application is unnecessary.

4.5.5. EXCLUSIVE_AREA QoS Policy no longer supported; documentation removed

To advance the deprecation of the EXCLUSIVE_AREA QoS Policy, RTI has removed the EXCLUSIVE_AREA QoS policy documentation. RTI no longer supports the use of this QoS policy. This change specifically targets the EXCLUSIVE_AREA QoS policy, eliminating the ability to set use_shared_exclusive_area. In future releases, RTI plans to remove Connext components that support or implement the EXCLUSIVE_AREA QoS Policy.

4.6. Third-Party Software Changes

The following third-party software is now used by Connext:

Table 4.1 New Third-Party Software

Third-Party Software

Version

y2038

20100403

The following third-party software used by Connext has been upgraded:

Table 4.2 Third-Party Software Upgrades

Third-Party Software

Old Version

New Version

InstallBuilder

21.6.0

23.10.1

For information on third-party software used by Connext products, see the “3rdPartySoftware” documents in your installation: <NDDSHOME>/doc/manuals/connext_dds_professional/release_notes_3rdparty.