The 7.5.21 RELIABILITY QosPolicy determines whether or not data published by a DataWriter will be reliably delivered by Connext DDS to matching DataReaders. The reliability protocol used by Connext DDS is discussed in 11. Reliable Communications.
With protocol-level reliability alone, the producing application knows that the information is received by the protocol layer on the consuming side. However, the producing application cannot be certain that the consuming application read that information or was able to successfully understand and process it. The information could arrive in the consumer’s protocol stack and be placed in the DataReader cache but the consuming application could either crash before it reads it from the cache, not read its cache, or read the cache using queries or conditions that prevent that particular DDS data sample from being accessed. Furthermore, the consuming application could access the DDS sample, but not be able to interpret its meaning or process it in the intended way.
The mechanism to let a DataWriter know to keep the DDS sample around, not just until it has been acknowledged by the reliability protocol, but until the application has been able to process the DDS sample is aptly called Application Acknowledgment. A reliable DataWriter will keep the DDS samples until the application acknowledges the DDS samples. When the subscriber application is restarted, the middleware will know that the application did not acknowledge successfully processing the DDS samples and will resend them.
Connext DDS supports three kinds of application acknowledgment, which is configured in the 7.5.21 RELIABILITY QosPolicy):
Note: Even in DDS_APPLICATION_EXPLICIT_ACKNOWLEDGMENT_MODE, some DDS samples may be automatically acknowledged. This is the case when DDS samples are filtered out by the reader using time-based filter, or using content filters. Additionally, when the reader is explicitly configured to use KEEP_LAST history kind, DDS samples may be replaced in the reader queue due to resource constraints. In that case, the DDS sample will be automatically acknowledged by the middleware if it has not been read by the application before it was replaced. To truly guarantee successful processing of DDS samples, it is recommended to use KEEP_ALL history kind.
void MyReaderListener::on_data_available(DDSDataReader *reader)
{ Foo sample; DDS_SampleInfo info; FooDataReader* fooReader = FooDataReader::narrow(reader); DDS_ReturnCode_t retcode = fooReader->take_next_sample( sample, info); if (retcode == DDS_RETCODE_OK) { if (info.valid_data) { // Process sample ... retcode = reader->acknowledge_sample(info); if (retcode != DDS_RETCODE_OK) { // Error } } } else { // Not OK or NO DATA } }
void MyReaderListener::on_data_available(DDSDataReader *reader)
{ ... // Loop while samples available for(;;) { retcode = string_reader->take_next_sample( sample, info); if (retcode == DDS_RETCODE_NO_DATA) { // No more samples break; } // Process sample ... } retcode = reader->acknowledge_all(); if (retcode != DDS_RETCODE_OK) { // Error } }
A DataWriter can get notification of delivery with Application Acknowledgment using two different mechanisms:
A DataWriter can use the wait_for_acknowledgments() operation to be notified when all the DDS samples in the DataWriter’s queue have been acknowledged. See 7.3.11 Waiting for Acknowledgments in a DataWriter.
retCode = fooWriter->write(sample, DDS_HANDLE_NIL);
if (retCode != DDS_RETCODE_OK) { // Error } retcode = writer->wait_for_acknowledgments(timeout); if (retCode != DDS_RETCODE_OK) { if (retCode == DDS_RETCODE_TIMEOUT) { // Timeout: Sample not acknowledged yet } else { // Error } }
Using wait_for_acknowledgments() does not provide a way to get delivery notifications on a per DataReader and DDS sample basis. If your application requires acknowledgment of message receipt, use the the second mechanism described below.
An application can install a DataWriter listener callback on_application_acknowledgment() to receive a notification when a DDS sample is acknowledged by a DataReader. As part of this notification, you can access:
For more information, see 7.3.6.1 APPLICATION_ACKNOWLEDGMENT_STATUS.
When the subscribing application confirms it has successfully processed a DDS sample, an AppAck RTPS message is sent to the publishing application. This message will be resent until the publishing application confirms receipt of the AppAck message by sending an AppAckConf RTPS message. See Figure 7.10: AppAck RTPS Messages Sent when Application Acknowledges a DDS Sample through Figure 7.12: AppAck RTPS Messages Sent as a Sequence of Intervals, Combined to Optimize for Bandwidth.
Figure 7.10: AppAck RTPS Messages Sent when Application Acknowledges a DDS Sample
Figure 7.11: AppAck RTPS Messages Resent Until Acknowledged Through AppAckConf RTPS Message
Figure 7.12: AppAck RTPS Messages Sent as a Sequence of Intervals, Combined to Optimize for Bandwidth
You can configure whether AppAck RTPS messages are sent immediately or periodically through the 8.6.1 DATA_READER_PROTOCOL QosPolicy (DDS Extension). The samples_per_app_ack (in Table 8.19 DDS_RtpsReliableReaderProtocol_t) determines the minimum number of DDS samples acknowledged by one application-level Acknowledgment message. The middleware will not send an AppAck message until it has at least this many DDS samples pending acknowledgment. By default, samples_per_app_ack is 1 and the AppAck RTPS message is sent immediately. Independently, the app_ack_period (in Table 8.19 DDS_RtpsReliableReaderProtocol_t) determines the rate at which a DataReader will send AppAck messages.
Application Acknowledgment is fully supported by RTI Persistence Service. The combination of Application Acknowledgment and Persistence Service is actually a common configuration. In addition to keeping DDS samples available until fully acknowledged, Persistence Service, when used in peer-to-peer mode, can take advantage of AppAck messages to avoid sending duplicate messages to the subscribing application. Because AppAck messages are sent to all matching writers, when the subscriber acknowledges the original publisher, Persistence Service will also be notified of this event and will not send out duplicate messages. This is illustrated in Figure 7.13: Application Acknowledgment and Persistence Service .
Application Acknowledgment is supported by RTI Routing Service: That is, Routing Service will acknowledge the DDS sample it has processed. Routing Service is an active participant in the Connext DDS system and not transparent to the publisher or subscriber. As such, Routing Service will acknowledge to the publisher, and the subscriber will acknowledge to Routing Service. However, the publisher will not get a notification from the subscriber directly.
© 2020 RTI