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