Many applications expect data to be sent and received periodically (or quasi-periodically). They typically expect at least one DDS data sample to arrive during each period; a failure of data to arrive may or may not indicate a serious problem, but is probably something about which the application would like to receive notifications. For example:
If any vehicle, any sensor, or any radar track fails to yield an update within its promised period, another part of the system, or perhaps its human operator, may need to take a corrective action.
(In addition to built-in deadline support, Connext DDS has other features useful to applications that publish and/or receive data periodically. For example, it’s possible to down-sample high-rate periodic data; see Subscribing Only to Relevant Data.
Deadline enforcement is comprised of two parts: (1) QoS policies that specify the deadline contracts and (2) listener callbacks that are notified if those contracts are violated.
Deadlines are enforced independently for DataWriters and DataReaders. However, the Deadline QoS policy, like some other policies, has request-offer semantics: the DataWriter must offer a level of service that is the same or better than the level of service the DataReader requests. For example, if a DataWriter promises to publish data at least once every second, it will be able to communicate with a DataReader that expects to receive data at least once every two seconds. However, if the DataReader declares that it expects data twice a second, and the DataWriter only promises to publish updates only once a second, they will not be able to communicate.
A DataWriter promises to publish data at a certain rate by providing a finite value for the Deadline QoS policy, either in source code or in one or more XML configuration files. (Both mechanisms are functionally equivalent; the News example in C, C++, Java, and Ada uses XML files. For more information about this mechanism, see the section on “Configuring QoS with XML” in the User's Manual.)
The file USER_QOS_PROFILES.xml in the News example for C, C++, Java, and Ada contains the following Deadline QoS policy configuration, which applies to both DataWriters and DataReaders:
<deadline> <period> <sec>2</sec> <nanosec>0</nanosec> </period> </deadline>
The DataWriter thus promises to publish at least one DDS data sample—of each instance—every two seconds.
If a period of two seconds elapses from the time the DataWriter last sent a DDS sample of a particular instance, the writer’s listener—if one is installed—will receive a callback to its on_offered_deadline_missed method. The News example does not actually install a DataWriterListener. See the section on requested deadlines below; the DataWriterListener works in a way that’s parallel to the DataReaderListener.
The DataReader declares that it expects to receive at least one DDS data sample of each instance within a given period using the Deadline QoS policy. See the example XML configuration above.
If the declared deadline period elapses since the DataReader received the last DDS sample of some instance, that reader’s listener—if any—will be invoked. The listener’s on_requested_deadline_missed() will receive a call informing the application of the missed deadline.
To install a DataReaderListener:
DDSDataReader* reader = participant->create_datareader( topic, DDS_DATAREADER_QOS_DEFAULT, &_listener, // listener DDS_STATUS_MASK_ALL); // all callbacks if (reader == NULL) { throw std::runtime_error("Unable to create DataReader"); }
DataReader reader = participant.create_datareader( topic, Subscriber.DATAREADER_QOS_DEFAULT, new ArticleDeliveryStatusListener(), // listener StatusKind.STATUS_MASK_ALL); // all callbacks if (reader == null) { throw new IllegalStateException("Unable to create DataReader"); }
declare readerListener : ArticleDeliveryStatusListener; begin reader := participant.Create_DataReader (topic.As_TopicDescription, DDS.Subscriber.DATAREADER_QOS_DEFAULT, readerListener'Unchecked_Access, -- listener DDS.STATUS_MASK_ALL); -- all callbacks if reader = null then Put_Line (Standard_Error, "Unable to create DataReader"); return; end if; end;
There are two listener-related arguments to provide:
Listener: The listener object itself, which must implement some subset of the callbacks defined by the DataReaderListener supertype.
Listener mask: Which of the callbacks you’d like to receive. In most cases, you will use one of the constants STATUS_MASK_ALL (if you are providing a non-null listener object) of STATUS_MASK_NONE (if you are not providing a listener). There are some cases in which you might want to specify a different listener mask; see the RTI Connext DDS Core Libraries User's Manual and API Reference HTML documentation for more information.
Let’s look at a very simple implementation of the on_requested_deadline_missed callback that prints the value of the key (i.e., the news outlet name) for the instance whose deadline was missed. You can see this in the News example provided with C, C++, and Java.
void ArticleDeliveryStatusListener::on_requested_deadline_missed( DDSDataReader* reader, const DDS_RequestedDeadlineMissedStatus& status) { DDS_KeyedString keyHolder; DDSKeyedStringDataReader* typedReader = DDSKeyedStringDataReader::narrow(reader); typedReader->get_key_value(keyHolder, status.last_instance_handle); std::cout << "->Callback: requested deadline missed: " << keyHolder.key << std::endl; }
public void on_requested_deadline_missed( DataReader reader, RequestedDeadlineMissedStatus status) { KeyedString keyHolder = new KeyedString(); reader.get_key_value_untyped(keyHolder, status.last_instance_handle); System.out.println("->Callback: requested deadline missed: " + keyHolder.key); }
procedure On_Requested_Deadline_Missed (Self : not null access Ref; The_Reader : in DDS.DataReaderListener.DataReader_Access; Status : in DDS.RequestedDeadlineMissedStatus) is pragma Unreferenced (Self); pragma Unreferenced (The_Reader); pragma Unreferenced (Status); begin Put_Line ("->Callback: requested deadline missed."); end On_Requested_Deadline_Missed;
Modify the file USER_QOS_PROFILES.xml to decrease the deadline to one second:
<deadline> <period> <sec>1</sec> <nanosec>0</nanosec> </period> </deadline>
Note that, if you have a DataReader- or DataWriter-level deadline specified (inside the file's datareader_qos or datawriter_qos elements, respectively)—possibly because you previously modified the configuration in Time-Based Filtering—it is overriding the topic-level configuration. Be careful that you don't modify a deadline specification that will only be overridden later and not take effect.
You will see output similar to Figure 1:
Figure 1 Using a Shorter Deadline
© 2015 RTI