Tuesday, August 10, 2010

My take on the new DDS C++ PSM

It has been a while since we've started the standardization of a new C++ API for DDS (namely the ISO C++ PSM for DDS). Now we are getting close, on principle the standard should be voted during the September meeting, yet there are still a few points to resolve among submitters. If I look back at the IDL-derived C++ API and what will be the new, SimD-inspired, API I believe the result is great. In this and subsequent post, I'll share with you an outlook of what our current proposal for the final C++ API standard looks like. Your comments will be useful as they might be able to still influence how the API will look like.

To start with, let's take a look at a simple writer:


int main(int, char**) {
int domainId = 0;

try {
// Create Domain + Topic + Pub
dds::domain::DomainParticipant dp(domainID);
dds::topic::Topic<MiB> topic("MessageInABottle", dp);
dds::pub::Publisher pub(dp);

// Create DataWriter
dds::pub::DataWriter<MiB> dw(pub);

// Write Sample
MiB sample(1, "Hello");

// You can write like this...
dw.write(sample);

// ...and like this (and there is more...)
dw << sample;
}
catch (const dds::core::Exception& e) {
std::cout << e << std::endl;
}

return 0;
}



Now we can look at a more "complex" example in which we set custom QoS on the Publisher and DataWriter:



int main(int, char**) {
int domainId = 0;

try {

// Create Domain + Topic + Pub
dds::domain::DomainParticipant dp(domainID);

dds::topic::Topic<MiB> topic("MessageInABottle", dp);

// Publisher
dds::qos::PublisherQos pubQos;
dds::qos::Partition partition("TheCoolAPI");
pubQos << partition;

dds::pub::Publisher pub(pubQos, dp);

// Subscriber
dds::qos::SubscriberQos subQos;
subQos << partition;
dds::sub::Subscriber sub(subQos, dp);

dds::qos::DataWriterQos dwQos;
dwQos << Reliable() << TransientDurability();

dds::pub::DataWriter<MiB> dw(topic, dwQos, pub);
MiB mib;
mib.msg() = "ciao";

// You can write like this...
dw.write(mib);

// ...and like this (and there is more...)
dw << mib;

}
catch (const dds::core::Exception& e) {
std::cout << e << std::endl;
}

return 0;
}


That's it for this post. I'll let you know digest the code and perhaps give some comments on how you like it. Next will be a post showing the reader side.

A+

2 comments:

davidk said...

Angelo,
What I intended as a brief question, has turned into a long list of questions. Please edit my comment to post whatever parts, if any, you think will help the overall discussion.
David K.


This C++ API is an enormous improvement over the original C++ mapping which really was painful.

The use of "<<" to attach QoS is an interesting choice. I compare this to a fluent style interface based on '.' and I'm guessing you chose an over-loadable operator to make it easy to add new QoS in the future.

A few questions about QoS 'attribute' classes and the new API:

1. Can QoS attributes be grouped into an object and then apply whole group to a DDS entity with a single <<? For example:

dds::qos:QoS qos << Reliable() << TransientDurability();

dw << qos;
dr << qos;


2. What happens when a QoS is applied to a DDS entity that doesn't accept that QoS? Compile error, exception, silent ignore?

3. Does >> work to extract the QoS from an entity? For example a Topic or an entity created with topic defaults?

4. Are the QoS attribute classes opaque? or do they have members/properties that can be get/set? I'm thinking specifically of scenarios where I load QoS setting from a file or transmit QoS as data inside another topic.

A broader example of what can be done more easily regarding QoS setting with the new API would be interesting, since QoS support is one of the most differentiating features of DDS.

Other questions:

If you think of readers and writers as containers, have covariance and contravariance been addressed? or do you have to read/write the exact type declared in the reader/writer template?

Can the samples stored in readers and writers be accessed with operator[]? (BTW, does the DDS standard require that the writer store the last sample sent for an instance or is that only part of the OpenSpliceDDS implementation?)


In the writer example the line:
mib.msg() = "ciao";

Are the parenthesis in ".msg()" intentional? Is this part of how the user defined IDL classes are mapped to C++?

That leads to a few other questions:
1) Can plain old classes be used as the template argument or must they be idlpp generated classes?

2) Do you follow the OMG IDL C++ mapping for user data classes or is there an implied new mapping for C++ that is now supported?

Does the new C++ mapping address and/or standardize the interface between the middleware implementation and the idl pre-processor? In my experience this one of the most awkward parts of DDS. For a variety of reasons it would be very helpful to be able to have direct (and simple) control over how application layer classes are mapped onto DDS classes. I could write a lot more on this subject ... if it's of interest we can carry that conversation on over email.

Angelo said...

Hello David,

I am glad you like the proposal for the new DDS C++ API. Concerning your questions, here are my answers:

1. The QoS grouping is not supported, however could be an interesting extension to reuse the same settings. What is supported right now is copy construction from related policies, yet that would not cover the case you are presenting below.

2. Some error can be detected at compile time, such as applying the wrong time or an unsupported policy. Other error, have to be detected at runtime since changing some policies is legal on inactive entities while illegal on active.

3. Yes the operator >> can be used to extract QoS from entities and policies from Qos.

4. QoS classes setter/getters as well as inserter/extractors for aggregated policies.

Finally, addressing the question on variance, the reference types defined by the spec as variant in the type parameter. The reader, writers are invariant in the type parameter. The issue is that if they would be co-variant we would risk to fill some attributes with default values w/o this being the real intention of the user.

A+