You are here: Part 2: Core Concepts > Sending Data > DataWriters > Application Acknowledgment

Application Acknowledgment

The 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 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.

Application Acknowledgment Kinds

Connext DDS supports three kinds of application acknowledgment, which is configured in the RELIABILITY QosPolicy):

  1. DDS_PROTOCOL_ACKNOWLEDGMENT_MODE (Default): In essence, this mode is identical to using no application-level acknowledgment. DDS samples are acknowledged according to the Real-Time Publish-Subscribe (RTPS) reliability protocol. RTPS AckNack messages will acknowledge that the middleware received the DDS sample.
  2. DDS_APPLICATION_AUTO_ACKNOWLEDGMENT_MODE: DDS samples are automatically acknowledged by the middleware after the subscribing application accesses them, either through calling take() or read() on the DDS sample. The DDS samples are acknowledged after return_loan() is called.
  3. DDS_APPLICATION_EXPLICIT_ACKNOWLEDGMENT_MODE: DDS samples are acknowledged after the subscribing application explicitly calls acknowledge on the DDS sample. This can be done by either calling the DataReader’s acknowledge_sample() or acknowledge_all() operations. When using acknowledge_sample(), the application will provide the DDS_SampleInfo to identify the DDS sample being acknowledge. When using acknowledge_all, all the DDS samples that have been read or taken by the reader will be acknowledged.
  4. 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.

Explicitly Acknowledging a Single DDS Sample (C++)

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
	}
}

Explicitly Acknowledging All DDS samples (C++)

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
	}
}

Notification of Delivery with Application Acknowledgment

A DataWriter can get notification of delivery with Application Acknowledgment using two different mechanisms:

Application-Level Acknowledgment Protocol

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 10 through Figure 12.

Figure 10 AppAck RTPS Messages Sent when Application Acknowledges a DDS Sample 

Figure 11 AppAck RTPS Messages Resent Until Acknowledged Through AppAckConf RTPS Message

Figure 12 AppAck RTPS Messages Sent as a Sequence of Intervals, Combined to Optimize for Bandwidth

Periodic and Non-Periodic AppAck Messages

You can configure whether AppAck RTPS messages are sent immediately or periodically through the DATA_READER_PROTOCOL QosPolicy (DDS Extension). The samples_per_app_ack (in 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 DDS_RtpsReliableReaderProtocol_t) determines the rate at which a DataReader will send AppAck messages.

Application Acknowledgment and Persistence Service

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 13.

Figure 13 Application Acknowledgment and Persistence Service

 

Application Acknowledgment and Routing 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.

© 2017 RTI