Scenario
I am trying to read samples (new, updated or disposed) using the interface on_data_available. The publisher is writing dispose and after that unregistering the instance. The subscriber is reading new or updated samples of an instance by read-method.
How can I get a notification when my DataReader receives a ‘dispose’ sample?
Solution
When a dispose arrives in a DataReader, the associated instance is marked as NOT_ALIVE_DISPOSED. Please note that a ‘dispose’ doesn’t deliver a separate sample. The only exception for that is the situation where no samples are available in your DataReader for the instance you dispose. In this case the middleware will generate a so-called ‘invalid’ sample. This ‘dummy’ sample allows you to be notified of instance state changes even if there’s no data for the instance in your DataReader.
Since you are performing a ‘read‘ and not a ‘take‘ (destructive read), there will normally be a sample available in your instance when the dispose arrives, so even though your listener is triggered, you won’t read any ‘disposed’ data in the way you perform ‘read’. You could still read them by doing two reads in your callback:
1. read (samples, info.
DDS::LENGTH_UNLIMITED,
DDS::NOT_READ_SAMPLE_STATE,
DDS::ANY_VIEW_STATE,
DDS::ALIVE_INSTANCE_STATE);
This gives you all unread samples of alive instances.
2. read (samples, info.
DDS::LENGTH_UNLIMITED,
DDS::ANY_SAMPLE_STATE,
DDS::ANY_VIEW_STATE,
DDS::NOT_ALIVE_DISPOSED_INSTANCE_STATE);
This gives you all samples for disposed instances. To prevent reading the ‘disposed’ data over and over again, you could consider performing a ‘take’ in step 2 instead of a read. Most applications are not interested in reading disposed data again. In case you are not interested in reading the samples again, an easier option is to use ‘take’ in all situations like this:
take (samples, info.
DDS::LENGTH_UNLIMITED,
DDS::ANY_SAMPLE_STATE,
DDS::ANY_VIEW_STATE,
DDS::ANY_INSTANCE_STATE);
Now you will get both your alive and disposed data in one single step.