Modern C++ API - DataReader::take(T &sample, dds::sub::SampleInfo &si) not working as expected

3 posts / 0 new
Last post
Offline
Last seen: 3 weeks 5 days ago
Joined: 08/25/2015
Posts: 32
Modern C++ API - DataReader::take(T &sample, dds::sub::SampleInfo &si) not working as expected

Hello,

One of our usecases requires the access to the SampleInfo data when retrieving data. The problem is, that DataReader::take() does not reset the SampleInfo's valid() when there is no data to read.

The documentation does not mention anything about this case (calling take() when there's no data available) but I would expect that SampleInfo::valid() returns false.

Here a small example:

dds::domain::DomainParticipant participant(0);

dds::topic::Topic<Foo> topic(participant, "Foo");

dds::pub::DataWriter<Foo> writer(dds::pub::Publisher(participant), topic);

dds::sub::DataReader<Foo> reader(dds::sub::Subscriber(participant), topic);

fprintf(stdout, "Give Reader/Writer some time ...\n");

sleep(2);

fprintf(stdout, "Publishing data ...\n");

Foo sample; sample.id(52);

writer.write(sample);

fprintf(stdout, "Reading the data published...\n");

int i = 0;

dds::sub::SampleInfo si;

while(true) {

 if (i++ > 10) break;

 sample.id(-1);

 reader->take(sample, si);

 fprintf(stdout, "Valid: %d - id = %d\n", si.valid(), sample.id());

 if (!si.valid()) break;

}
 

And the output:

Give Reader/Writer some time ...
Publishing data ...
Reading the data published...
Valid: 1 - id = 52
Valid: 1 - id = -1
...

Is this the expected behaviour?

 

Thx,

Christian Ehrlicher

 

Offline
Last seen: 1 month 3 weeks ago
Joined: 01/10/2013
Posts: 26

Hi Christian, 

Thanks for bringing this up. You're right, this is not the correct behavior. At the moment, that API does not provide a good way for the user ot know if there was data or not. I will file an issue to fix this in future releases. For now, a workaround could be to pass in a new SampleInfo object to each call to take() and then check if it has been updated with values. For example, you can use the SampleInfo::publication_sequence_number() and compare it against rti::core::SequenceNumber::unknown(). If there was data then this should be a valid sequence number, otherwise the value will not change from the initial unknown value. 

Also, is there a specific reason that you are using this take API? This API takes the next sample in the reader's queue one at a time, making a copy of the data into the sample that you provide to the API. There are also a number of APIs that will not make a copy of the data and instead will provide you with a loan of all of the samples in the reader's queue at the time. There is a good example of using the different read and take APIs here: 

https://community.rti.com/static/documentation/connext-dds/5.2.0/doc/api/connext_dds/api_cpp2/group__DDSReaderExampleModule.html

Please let me know if you have any questions. 

Offline
Last seen: 3 weeks 5 days ago
Joined: 08/25/2015
Posts: 32

Hi,

 

thx for your reply. My current workaround is to use an empy SampleInfo() - object for every call and check for valid() there. Maybe remembering SampleInfo::publication_sequence_number() and check if it has changed will avoid the create/destroy of the SampleInfo object... I'll check this.

The reason why I'm using take() is that I reimplemented a very small subset of the connext request/reply functionality with the modern C++ API. And here the throuput of the request/reply does not (yet) matter because we normally handle requests which are generated by user input.

 

Thx,

Christian