4.2.1. RTI Connext Core Libraries¶
The following issues affect backward compatibility in the Core Libraries starting in Release 6.1.0. Issues in the Core Libraries may affect components that use these libraries, including services and tools.
4.2.1.1. Configuration Changes¶
4.2.1.1.1. Property name typos are now errors, not warnings¶
Connext 6.1.0 provides out-of-the-box stricter property validation than
earlier releases. In the following XML configuration, the property
ignore_sequence_bounds
contains a typo:
<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://community.rti.com/schema/6.1.0/rti_dds_profiles.xsd">
<qos_profile name="Example_Profile" base_name="BuiltinQosLib::Generic.StrictReliable">
<datareader_qos>
<property>
<value>
<element>
<name>dds.type_consistnecy.ignore_sequence_bounds</name>
<value>true</value>
</element>
</value>
</property>
</datareader_qos>
</qosProfile>
</dds>
Previously, in 6.0.1, a typo in the name of a property within a well-known namespace was reported out-of-the-box as a warning, the property was ignored, and the creation of the entity was successful. For the example above, in 6.0.1 you would see the following:
[D0000|Sub(80000009)|T=Example MyType|CREATE Reader]
DDS_PropertyQosPolicy_validatePropertyNames:Unexpected property:
dds.type_consistnecy.ignore_sequence_bounds. Closest valid property:
dds.type_consistency.ignore_sequence_bounds
In 6.1.0, a typo in the name of a property within a well-known namespace is reported out-of-the-box as an error and the creation of the entity fails. For the example above, you will see the following:
[0x0101C928,0x1845FBA5,0xE53A39B9:0x80000009{E=Su,D=0}|CREATE DR WITH TOPIC Example MyType]
DDS_PropertyQosPolicy_validateEntityPropertyNames:Unexpected property:
dds.type_consistnecy.ignore_sequence_bounds. Closest valid property:
dds.type_consistency.ignore_sequence_bounds. If you wish to proceed with
this property name anyway, change
'dds.participant.property_validation_action' to 'VALIDATION_ACTION_SKIP' or
'VALIDATION_ACTION_WARNING'.
[0x0101C928,0x1845FBA5,0xE53A39B9:0x80000009{E=Su,D=0}|CREATE DR WITH TOPIC Example MyType]
DDS_DataReaderQos_is_consistentI:inconsistent QoS property
[0x0101C928,0x1845FBA5,0xE53A39B9:0x80000009{E=Su,D=0}|CREATE DR WITH TOPIC Example MyType]
DDS_Subscriber_create_datareader_disabledI:ERROR: Inconsistent QoS
You can go back to the 6.0.1 behavior where the typo is reported as a warning
by setting the property dds.participant.property_validation_action
to
VALIDATION_ACTION_WARNING.
You can also go back to the 6.0.0 behavior where validation was skipped
by setting the dds.participant.property_validation_action
to
VALIDATION_ACTION_SKIP.
The property dds.participant.property_validation_action
accepts the
following values:
VALIDATION_ACTION_EXCEPTION: Validate properties. Upon failure, log errors and fail.
VALIDATION_ACTION_WARNING: Validate properties. Upon failure, log warnings and do not fail.
VALIDATION_ACTION_EXCEPTION: Skip validation.
See PROPERTY QosPolicy, in the RTI Connext Core Libraries User’s Manual for more information.
4.2.1.1.2. Error reported if load_plugin property not specified in properties of external plugin¶
Connext 6.1.0 will report an error when parsing the properties of an external
plugin (e.g., RTI Security Plugins) if the load_plugin
property for the
plugin is not defined. Consider the following example configuration for the
Security Plugins:
<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://community.rti.com/schema/6.1.0/rti_dds_profiles.xsd">
<qos_profile name="Example_Profile" base_name="BuiltinQosLib::Generic.StrictReliable">
<domain_participant_qos>
<property>
<value>
<element>
<name>com.rti.serv.secure.create_function</name>
<value>RTI_Security_PluginSuite_create</value>
</element>
</value>
</property>
</domain_participant_qos>
</qosProfile>
</dds>
Even though the com.rti.serv.secure.create_function
property is legal and
it does not contain typos, in 6.1.0, you will see the following error
when running with the above configuration, because the property
com.rti.serv.load_plugin
is not defined:
DDS_PropertyQosPolicy_validateEntityPropertyNames:Unexpected property:
com.rti.serv.secure.create_function. Closest valid property:
rti.monitor.create_function. If you wish to proceed with this property name
anyway, change 'dds.participant.property_validation_action' to
'VALIDATION_ACTION_SKIP' or 'VALIDATION_ACTION_WARNING'.
DDS_DomainParticipantQos_is_consistentI:inconsistent QoS property
DDS_DomainParticipantFactory_set_default_participant_qosI:ERROR: Inconsistent QoS
DDS_DomainParticipantFactory_load_profilesI:!set default DomainParticipant Qos
DDS_DomainParticipantFactory_create_participant_disabledI:ERROR: loading profiles
To fix the problem, make sure that the load_plugin
property for the plugin
is defined:
<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://community.rti.com/schema/6.1.0/rti_dds_profiles.xsd">
<qos_profile name="Example_Profile" base_name="BuiltinQosLib::Generic.StrictReliable">
<domain_participant_qos>
<property>
<value>
<element>
<name>com.rti.serv.load_plugin</name>
<value>com.rti.serv.secure</value>
</element>
<element>
<name>com.rti.serv.secure.create_function</name>
<value>RTI_Security_PluginSuite_create</value>
</element>
</value>
</property>
</domain_participant_qos>
</qosProfile>
</dds>
4.2.1.1.3. Instances no longer disposed by default when unregistered¶
The default value of autodispose_unregistered_instances in the WRITER_DATA_LIFECYCLE QoS Policy has changed from TRUE to FALSE. As a result, instances are no longer disposed by default when they are unregistered. Disposing an instance and unregistering from an instance are two distinct actions that a DataWriter can take. Therefore, in the majority of use cases, it is better and more transparent to explicitly perform each action when appropriate in your application rather than relying on Connext to perform either action automatically.
If the new default of FALSE does not work for your application, set it to TRUE.
In addition, the autodispose_unregistered_instances setting no longer applies to a DataWriter deletion. See Section 4.2.1.8.1 for details.
4.2.1.1.4. Inconsistent QoS error when setting availability.enable_required_subscriptions to TRUE and history kind to KEEP_LAST on DataWriter¶
Setting enable_required_subscriptions
in the
AVAILABILITY QoS Policy now
requires a history kind of KEEP_ALL. The reason is that not all samples
can be guaranteed to be delivered to the required DataReaders if history kind is
KEEP_LAST.
4.2.1.1.5. TYPE_CONSISTENCY_ENFORCEMENT QoS Policy has more permissive default values for ignore_sequence_bounds and ignore_string_bounds¶
The TYPE_CONSISTENCY_ENFORCEMENT QoS Policy has new default values for two of its boolean members: ignore_sequence_bounds and ignore_string_bounds. To comply with the OMG ‘Extensible and Dynamic Topic Types for DDS’ specification, version 1.3, the default values have changed from FALSE to TRUE.
As a result of this change, out of the box in 6.1.0, a DataWriter publishing a Topic with a type that contains a sequence member with a maximum bound ‘A’ will match with a DataReader subscribing to the same Topic using a type where the same sequence member has a smaller maximum bound.
Samples received by the DataReader will fail to be deserialized and be dropped if the number of elements in the sequence is larger than the maximum allowed by the DataReader type.
For example:
struct MyType1 {
sequence<long, 100> m1;
}
struct MyType2 {
sequence<long, 50> m1;
}
In earlier releases, a DataWriter publishing MyType1 and a DataReader subscribing to MyType2 did not match out of the box. In 6.1.0, the entities match. However, if the DataReader receives a sample where m1 has 8 elements, it will log a deserialization error and the sample will be reported as lost with the reason DDS_LOST_BY_DESERIALIZATION_FAILURE.
4.2.1.1.6. Removed refilter field in HISTORY QoS Policy¶
The refilter
field in the HISTORY QoS Policy has been removed along with the
associated public enum DDS_RefilterQosPolicyKind. If you are using this QoS
setting, you will need to remove it from any source code and XML configuration
files, and recompile your application.
The filtering behavior of a DataWriter can now only be controlled through
the max_remote_reader_filters
field in the DATA_WRITER_RESOURCE_LIMITS QoS
Policy. The behavior of max_remote_reader_filters
has not changed.
4.2.1.1.7. Deprecated transport.use_510_compatible_locator_kinds¶
The use_510_compatible_locator_kinds
transport property was used to communicate
over shared memory or UDPv6 between Connext 5.2.0 (or later) and a previous
release.
This property is deprecated in Connext 6.1.0. Even though it is still
supported, the new minimum_compatibility_version
property is recommended. Set
the value of minimum_compatibility_version
to 5.1.0
to indicate that the transport
should be compatible with Connext 5.1.0.
4.2.1.2. API Changes¶
The following Application Program Interfaces (APIs) have been changed or deprecated in 6.1.0. For new APIs, see What’s New in 6.1.0.
See also Section 4.2.2 for Code Generator related changes.
4.2.1.2.1. Migrating to the new C# API¶
This release includes a new .NET Standard 2.0-compatible C# language binding
(see Build applications for .NET 5 using new modern, multi-platform C# language binding, in What’s New in 6.1.0),
which will replace the previous binding. The new C# binding has to be installed
with an additional .rtipkg
file.
The old binding is deprecated and will be removed in the next major release.
You should write new .NET components in your system using the new binding and consider migrating existing components. The old binding will still receive updates for critical issues, but won’t include new features or improvements.
The new binding has a few limitations in this first release, explained in the release notes.
4.2.1.2.1.1. Advantages of the new binding¶
The new C# binding offers a number of advantages with respect to the old one:
It is multi-platform (the old binding runs only on Windows®).
It runs on .NET 5 and other .NET Standard 2.0-compatible systems, not just .NET Framework.
It provides a modern and idiomatic C# API that uses common C# interfaces, patterns, and conventions.
It no longer requires compiling user types in C++/CLI; both the API and the generated code are C#.
The type and method documentation is included in the assembly and visible with IntelliSense.
It is distributed as a NuGet package, making it easier to use and deploy. The NuGet package transparently manages the native dependencies for the right target.
4.2.1.2.1.2. Migrating to the new binding¶
If you’re planning to move your .NET Framework applications to .NET 5, you will need to migrate to the new Connext C# binding. The old one runs only on .NET Framework.
Even if you plan to continue using .NET Framework for now, you can start the migration. The new binding also supports .NET Framework 4.6.1-4.8, and both bindings can coexist within the same .NET assembly, so you can port your applications incrementally (you can’t, however, pass objects created by one API to methods of the other one). Like any other DDS application, applications using either binding will interoperate on the wire.
To start using the new binding in an existing code base, add the
Rti.ConnextDds
NuGet package to your .csproj
files.
> dotnet add package Rti.ConnextDds
By default, the package is downloaded from nuget.org. This package requires
a license to run your applications. To use the package from your Connext
installation, run the following command before dotnet add
:
> dotnet nuget add source <installation dir>/lib/dotnet -n RTI
Note
After installing the .NET package, the RTI Launcher GUI will not be able
to generate code for the C# Language option. Use the rtiddsgen command-line
option -language C#
instead.
4.2.1.2.1.3. Tips for users of the old binding¶
There are a few key differences in the way you write your applications using the new and the old bindings. (This section is also helpful if you are familiar with the Connext Java binding, which is similar to the old C# binding.)
Error reporting. The new binding reports errors exclusively as exceptions. In the old binding, some methods may report an error in the creation of some objects by returning
null
.
Object lifecycle. Both bindings use the factory pattern for
Entity
-derived objects. However, the way they are deleted is different:In the old binding, the factory type provided a
delete_*
method as well as adelete_contained_entities
method when necessary:DomainParticipant participant = DomainParticipantFactory.get_instance().create_participant(0, ...); // ... Topic topic = participant.create_topic("HelloWorld", ...); // ... participant.delete_contained_entities(); DomainParticipantFactory.get_instance().delete_participant(participant);
In the new binding, types that can be explicitly deleted implement
IDisposable
, and their Dispose() method automatically deletes the contained entities if needed.DomainParticipant participant = DomainParticipantFactory.Instance.CreateParticipant(0); // ... Topic<Foo> topic = participant.CreateTopic<Foo>("HelloWorld"); // ... participant.Dispose();
using DomainParticipant participant = DomainParticipantFactory.Instance.CreateParticipant(0); // ... Topic<Foo> topic = participant.CreateTopic<Foo>("HelloWorld"); // participant.Dispose() called when scope ends
Generic programming. The new binding uses generic classes. For example, in the new binding, a
DataReader
for the type Foo isDataReader<Foo>
. In the old binding, this type was generated and called FooDataReader.
Type registration. The new binding registers data types automatically upon the creation of a
Topic<T>
. The old binding required a explicit call toFooTypeSupport.register_type(participant, typeName)
.
Status updates (listeners). The new API defines C# events for each
Entity
to notify of updates to each status. The old API provided listener interfaces that had to be implemented and attached to the Entity.This example compares how to handle two DataWriter statuses using each binding.
class MyWriterListener : DataWriterListener { public override void on_publication_matched(DataWriter writer, ref PublicationMatchedStatus status) { // handle PublicationMatchedStatus update } public void on_offered_deadline_missed(DataWriter writer, ref OfferedDeadlineMissedStatus status) { // handle OfferedDeadlineMissedStatus update } } // ... var writer = publisher.create_datawriter( topic, Publisher.DATAWRITER_QOS_DEFAULT, null, StatusKind.STATUS_MASK_NONE); var listener = new MyWriterListener(); writer.set_listener( listener, StatusKind.PUBLICATION_MATCHED_STATUS | StatusKind.OFFERED_DEADLINE_MISSED_STATUS);
In the new API, the entity contains an event for each status that can receive updates:
var writer = publisher.CreateDataWriter(topic); writer.PublicationMatched += (writer, status) => { // handle PublicationMatchedStatus update }; writer.OfferedDeadlineMissed += (writer, status) => { // handle OfferedDeadlineMissedStatus update };
The old API allows setting the listener in the constructor. In the new API, the constructor receives a
preEnableAction
argument that allows performing an action on the entity being created right before it is enabled. This can be used to set the event handlers.var writer = publisher.CreateDataWriter( topic, preEnableAction: writer => { writer.PublicationMatched += OnPublicationMatched; writer.OfferedDeadlineMissed += OnOfferedDeadlineMissed; });
Reading data. The methods for reading data are significantly different.
Compare the following code in the old API with the code in the new API that follows.
FooSeq data_seq = new FooSeq(); SampleInfoSeq info_seq = new SampleInfoSeq(); try { reader.read( // or .take( sampleSeq, infoSeq, ResourceLimitsQosPolicy::LENGTH_UNLIMITED, SampleStateKind::ANY_SAMPLE_STATE, ViewStateKind::ANY_VIEW_STATE, InstanceStateKind::ANY_INSTANCE_STATE); for (int i = 0; i < sampleSeq.length; i++) { SampleInfo info = info_seq.get_at(i); if (!info.valid_data) { Foo data = data_seq.get_at(i); // use data } } reader.return_loan(sampleSeq, infoSeq); } catch(Retcode_NoData) { }
In the new API, a single,
IDisposable
andIEnumerable
collection provides the data and the info. When no data is available, the reader returns an empty collection instead of throwing an exception. In both bindings, the data is loaned. In the new binding, the loan is returned withDispose()
(here called automatically at the end of the scope of theusing
block), instead ofreturn_loan()
.using (LoanedSamples<Foo> samples = reader.Read()) // or .Take() { foreach (LoanedSample<Foo> sample in samples) { if (sample.Info.ValidData) { Foo data = sample.Data; // use data } } }
When the
SampleInfo
is not relevant, the code can be simplified further:using (LoanedSamples<Foo> samples = reader.Read()) // or .Take() { foreach (Foo data in samples.ValidData()) { // use data } }
To copy the data, the generated data types provide a constructor,
new Foo(data)
.In the new API,
Read()
andTake()
receive no arguments. The methodSelect()
allows specifying all the optional arguments.Select()
replaces all the other variations ofread
andtake
in the old API. For example, instead ofreader.take_w_condition(...)
, usereader.Select().WithCondition(...).Take()
.The new API also provides a new method,
reader.TakeAsync()
. This methods returns anIAsyncEnumerable
that provides the data asynchronously as it is received.For more examples, in the API Reference, under Modules > Programming Snippets, select Subscription Examples and IDL examples.
Managing XML profiles. In the new binding, XML-defined QoS profiles, types, and applications are managed by the
QosProvider
class, instead of theDomainParticipantFactory
.The
QosProvider
should also be used to create entities with an XML QoS profile.var writer = publisher.create_datawriter_with_profile( topic, "MyQosLibrary", "MyQosProfile", null, StatusMask.STATUS_MASK_NONE);
In the new API, you can use
QosProvider.Default
:var writerQos = QosProvider.Default.GetDataWriterQos("MyQosLibrary::MyQosProfile"); var writer = publisher.CreateDataWriter(topic, writerQos);
To configure which profiles are loaded by default, instead of using
DomainParticipantFactoryQos.profile
, useQosProvider.SetDefaultProviderParams()
.Or create a new
QosProvider
to load a specific file:var qosProvider = new QosProvider("my_profiles.xml"); var writerQos = qosProvider.GetDataWriterQos("MyQosLibrary::MyQosProfile"); var writer = publisher.CreateDataWriter(topic, writerQos);
Immutable types. Some types in the new API are immutable and implement a “non-destructive mutation” pattern. All QoS types follow this pattern.
This makes the syntax to configure a QoS policy quite different. Compare the code required to create a DataReader with two QoS policies using the old and the new binding.
var readerQos = new DataReaderQos(); subscriber.get_default_datareader_qos(readerQos); readerQos.reliability.kind = ReliabilityQosPolicyKind.RELIABLE_RELIABILITY_QOS; readerQos.history.kind = HistoryQosPolicyKind.KEEP_LAST_HISTORY_QOS; readerQos.history.depth = 10; reader = subscriber.create_datareader(topic, readerQos, null, StatusMask.STATUS_MASK_NONE);
In the new binding, each “edit” to a QoS object creates a new object that contains the values of the original object plus the edits.
var readerQos = subscriber.DefaultDataReaderQos .WithReliability(policy => policy.Kind = ReliabilityKind.Reliable) .WithHistory(policy => { policy.Kind = HistoryKind.KeepLast; policy.Depth = 10; }); var reader = subscriber.CreateDataReader(topic, readerQos);
Use of properties instead of getters or setters. The new binding prefers C# properties over getter/setter methods in most cases. You may find that a method in the old API (such as
subscriber.get/set_default_datareader_qos()
) is a property in the new API (subscriber.DefaultDataReaderQos
)For more information, see the API Reference, under Modules > Programming Snippets > Entity Examples.
4.2.1.2.2. Warning for C++/CLI language option¶
This release includes a new C# language binding for .NET Standard 2.0 ,
which will replace the previous binding. The new C# binding has to be installed
with an additional .rtipkg
file. (See Section 4.2.1.2.1.)
Using the -language C#
option without the additional package will
continue to generate code for the old API, but will print a warning that
the old binding will be removed in a future release.
When you install the new package, -language C#
will stop printing the
warning and use the new binding. (-language C++/CLI
produces the same
warning, but is not supported in the new API.)
4.2.1.2.3. Changes to SHMEM Transport APIs¶
The signature of the API that creates a new SHMEM transport instance in C
has changed. It includes a new parameter called minimum_compatibility_version
.
NDDS_Transport_Plugin* NDDS_Transport_Shmem_create(
NDDS_Transport_Address_t *default_network_address_out,
const struct DDS_PropertyQosPolicy *property_in,
const struct DDS_ProductVersion_t *minimum_compatibility_version);
If you were calling NDDS_Transport_Shmem_create before, you must modify the
function call to migrate your applications to 6.1.0. You must now add a third
parameter, the minimum_compatibility_version
.
The created shared memory transport plugin will be compatible with the Connext
version given in this parameter. Provide NULL
as the argument to impose no
compatibility restrictions. Doing so achieves the same behavior as in 6.0.0 and
6.0.1, where NDDS_Transport_Shmem_create
did not have the
minimum_compatibility_version
parameter. To be compatible with releases earlier
than 6.0.0, set the field to the version of the release that you want to be
compatible with.
minimum_compatibility_version
was added to support a new feature that allows
capturing network traffic into a pcap file from a DomainParticipant. For more information on
the new network capture feature in this release,
see Network Capture in the RTI Connext Core Libraries User’s Manual.
4.2.1.2.4. Modern C++ API: Constructor and listener setters behave as they used to, but you should use new APIs¶
Starting in this release, entities expect their listeners to be passed as a
std::shared_ptr
. Previously, listeners were expected as raw pointers.
Example of the new API:
class MyReaderListener : public dds::sub::DataReaderListener<Foo> {
// …
} ;
// …
auto my_listener = std::make_shared<MyReaderListener>();
dds::sub::DataReader<Foo> reader(subscriber, topic, qos, my_listener);
This change simplifies the lifecycle of the listener and its entity. Previously, an entity with a listener was “retained” (it wouldn’t be automatically destroyed even if its reference count reached zero) to allow for the application to unset the listener and delete it.
Now an Entity with a listener holds a reference to the shared_ptr
, keeping
the listener alive while the Entity is alive. If the Entity reference count
reaches zero, it is destroyed even if it has a listener.
The following APIs have changed:
Entity constructors now take a
shared_ptr
to the listener. Constructors taking a raw pointer are deprecated and may be removed in a future version.
New functions in each Entity called
set_listener
andget_listener
have been added. They receive and return ashared_ptr
to the listener. The previous functions that received and returned a raw pointer are deprecated and may be removed in a future version.
The
rti::core::ListenerBinder
utility is deprecated because it is no longer needed and may be removed in a future version.The deprecated constructor and listener setters behave as they used to (they prevent the automatic destruction of the entity), so existing code that upgrades to this version will not see any difference. However, it is recommended that applications transition to the new APIs.
4.2.1.2.5. Removed some enumerators from DDS_SampleRejectedStatusKind¶
In this release, you can identify why a subscribing application is not seeing samples using new statistics for lost, rejected, and dropped samples. See What’s New in 6.1.0
As a result of these changes, the following enumerators from SampleRejectedStatusKind have been removed:
DDS_REJECTED_BY_UNKNOWN_INSTANCE
DDS_REJECTED_BY_REMOTE_WRITERS_PER_SAMPLE_LIMIT
DDS_REJECTED_BY_VIRTUAL_WRITERS_LIMIT
DDS_REJECTED_BY_REMOTE_WRITERS_PER_INSTANCE_LIMIT
DDS_REJECTED_BY_REMOTE_WRITERS_LIMIT
If you are using any of these enumerators in your application, they will need to be removed and you will need to recompile your application.
4.2.1.2.6. DataWriter::get_matched_subscriptions and DataReader::get_matched_publications return not alive entities¶
Previously, the DDS::DataWriter::get_matched_subscriptions
and
DDS::DataReader::get_matched_publications
APIs only returned instance
handles for remote entities that were alive. This was not compliant with
the OMG Data Distribution Service (DDS) standard API, version 1.4.
Now, these APIs return the instance handles
for any matching remote entities, including those that are not alive.
If you want to use the old behavior, where these APIs only returned instance
handles for remote entities that were alive, use the APIs along with the
new APIs DDS::DataWriter::is_matched_subscription_active()
(to know which matched DataReaders are not active) and
DDS::DataReader::is_matched_publication_alive()
(to know which matched DataWriters
are not alive).
4.2.1.2.7. Changed get_matched_publication_data and get_matched_subscription_data return value¶
DDS_DataWriter_get_matched_subscription_data
and
DDS_DataReader_get_matched_publication_data
have changed their return value from
DDS_RETCODE_PRECONDITION_NOT_MET to DDS_RETCODE_BAD_PARAMETER when the instance handle
does not correspond to any matched endpoint. This change also affects APIs that use
exceptions instead of return codes (Modern C++, Java, and .NET). The new return value
is now consistent with the API documentation.
4.2.1.3. Library Size¶
The following table shows the different sizes of the main libraries in Connext 6.1.0 versus 6.0.1, for a Linux architecture. The size of the libraries has increased due to the addition of new code; however, the changes are not significantly higher.
Note
The libraries tested are the release versions. The value for each of the
libraries has been obtained as the text
size displayed when using the
size
command on Linux.
Library |
Size in 6.0.1 |
Size in 6.1.0 |
---|---|---|
Traditional C++ API (libnddscpp) |
1.49 MB |
1.53 MB |
Modern C++ API (libnddscpp2) |
1 MB |
1.14 MB |
C API (libnddsc) |
5.86 MB |
6.23 MB |
Core Library (libnddscore) |
6.07 MB |
6.57 MB |
4.2.1.4. Memory Consumption¶
In general, 6.1.0 applications consume equivalent heap memory to 6.0.1.
Note
These numbers should be taken as a rough estimation due to the nature of how Connext reserves memory.
Entity |
6.0.1 Size |
6.1.0 Size |
Diff (Bytes) |
Diff (%) |
---|---|---|---|---|
Participant Factory |
74.4 KB |
62.0 KB |
-1,27 MB |
-16.63 |
Participant |
18,12 MB |
1899.6 KB |
0.00 |
0.00 |
Type |
1.4 KB |
1.4 KB |
0.00 |
0.00 |
Topic |
2.1 KB |
1.9 KB |
-218.00 |
-10.05 |
Subscriber |
9.4 KB |
9.4 KB |
0.00 |
0.00 |
Publisher |
3.7 KB |
3.7 KB |
0.00 |
0.00 |
DataReader |
70.0 KB |
70.0 KB |
-7.00 |
-0.01 |
DataWriter |
40.9 KB |
40.9 KB |
-14.00 |
-0.03 |
Instance |
0.5 KB |
0.5 KB |
-12.00 |
-2.41 |
Sample |
1.3 KB |
1.3 KB |
-7.00 |
-0.51 |
Remote Readers |
7.2 KB |
6.9 KB |
-309.00 |
-4.22 |
Remote Writers |
15.1 KB |
15.1 KB |
12.00 |
0.08 |
Reader Instance |
876 Bytes |
888 Bytes |
12.00 |
1.37 |
Reader Samples |
917 Bytes |
917 Bytes |
0.00 |
0.00 |
Remote Participant |
75.3 KB |
75.2 KB |
-146.00 |
-0.19 |
4.2.1.5. Network Performance¶
In general, 6.1.0 applications have the same performance as in 6.0.1 for user data exchange. However, some significant performance and scalability improvements have been done in areas such as discovery and security. For detailed information on these improvements, see Section 4.2.1.6.
The following numbers are taken using RTI Perftest 3.1 for a Reliable scenario with unkeyed data.
Latency
Sample Size (Bytes)
Latency in 6.0.1 (microSec)
Latency in 6.1.0 (microSec)
Diff in microSec
Diff in %
32
21.00
21
0.00
0.00
64
21.00
21
0.00
0.00
128
22.00
22
0.00
0.00
256
22.00
22
0.00
0.00
512
23.00
23
0.00
0.00
1 KB
24.00
25
1.00
4.17
8 KB
45.00
45
0.00
0.00
61.5 KB
109.00
109
0.00
0.00
100 KB
149.00
150
1.00
0.67
500 KB
573.00
575
2.00
0.35
1 MB
1007.00
1008
1.00
0.10
1.5 MB
1668.00
1668
0.00
0.00
4 MB
4110.00
4114
4.00
0.10
10 MB
12704.00
11091
-1613.00
-12.70
Throughput
Sample Size (Bytes)
Throughput in 6.0.1 (Mbps)
Throughput in 6.1.0 (Mbps)
Diff in Mbps
Diff in %
32
1232.80
1222.8
-10.00
-0.81
64
2196.50
2219.0
22.50
1.02
128
3781.10
3553.3
-227.80
-6.03
256
5770.70
5621.7
-149.00
-2.58
512
7816.80
7723.5
-93.30
-1.19
1 KB
9414.30
9621.9
207.60
2.21
8 KB
9845.00
9844.9
-0.10
-0.00
61.5 KB
9916.00
9916.0
0.00
0.00
100 KB
9408.40
9911.1
502.70
5.34
500 KB
9061.90
9060.3
-1.60
-0.02
1 MB
8143.40
8124.9
-18.50
-0.23
1.5 MB
8998.50
9098.6
100.10
1.11
4 MB
7967.60
8702.6
735.00
9.22
10 MB
7156.80
8129.6
972.80
13.59
4.2.1.6. Discovery Performance¶
Participant Discovery and Endpoint Discovery times have improved in 6.1.0 compared to 6.0.1.
The following table displays an example of this improvement.
Note
This table shows the time to complete Endpoint Discovery based on the number of Endpoints. For each experiment (row), half the endpoints are DataReaders and half are DataWriters. Each Endpoint is assigned to a different Participant, and each Participant belongs to a separate process. All processes (and therefore all Participants and Endpoints) are deployed in a round-robin fashion across eight Linux nodes in an isolated lab. All nodes are connected through 1Gbps NICs to the same network.
Number of Endpoints |
Discovery Time in 6.0.1 (Seconds) |
Discovery Time in 6.1.0 (Seconds) |
Diff (Seconds) |
---|---|---|---|
50 |
2.630 |
2.643 |
0.01 |
75 |
3.446 |
3.085 |
-0.36 |
100 |
4.011 |
3.333 |
-0.68 |
125 |
5.165 |
4.274 |
-0.89 |
150 |
6.148 |
5.241 |
-0.91 |
175 |
8.081 |
6.462 |
-1.62 |
200 |
9.589 |
7.177 |
-2.41 |
225 |
12.328 |
8.167 |
-4.16 |
250 |
17.073 |
9.971 |
-7.10 |
275 |
18.369 |
12.268 |
-6.10 |
300 |
21.289 |
13.923 |
-7.37 |
These improvements are not only extensive but even more pronounced when using RTI Security Plugins. See Section 4.2.4.11.
4.2.1.7. RTI Connext Micro Compatibility¶
Connext Micro does not interoperate with DataWriters that send compressed data. For more information about compression, see the DATA_REPRESENTATION QosPolicy section, in the RTI Connext Core Libraries User’s Manual.
4.2.1.8. Miscellaneous¶
4.2.1.8.1. autodispose_unregistered_instances setting no longer applies when deleting DataWriter¶
In previous releases, the deletion of a reliable DataWriter where
autodispose_unregistered_instances
is set to TRUE may not have caused the
DataWriter’s registered instances to transition to DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE
on the reliable DataReader side. Instead, some instances may have transitioned to the
DDS_NOT_ALIVE_NO_WRITERS state. To address this issue, DataWriter deletion is now
treated differently than an explicit call to DataWriter::unregister_instance
.
Therefore, the autodispose_unregistered_instances
setting no longer applies
during DataWriter deletion and only applies when a DataWriter calls unregister_instance
explicitly. Deletion of a DataWriter does not dispose of instances anymore, regardless
of how autodispose_unregistered_instances
is set.
In addition, the default value of autodispose_unregistered_instances
has
changed to FALSE. See Section 4.2.1.1.3
for additional details.
4.2.1.8.2. New Durable Writer History (database) schema¶
In 6.1.0, the schema of the storage files and tables created by a DataWriter using durable writer history to store DDS samples and instances has changed. Therefore, you cannot use the files and/or tables generated with previous releases.
If you have this requirement, contact RTI Support at support@rti.com.