Hello everyone,
I am interested in content filtered topic because it appies to pub rather than sub.
According to https://community.rti.com/examples/content-filtered-topic , it filters a seqence of dds samples.
but is it possible filtering content itself?
My case is that I have many devices distributed into different partitions, and want pub partiton configuration XML files to these device.
There are two solutions I think,
One is pub the whole configuration XML file including every partition and subers process this file on its side, which may cause bandwidth cost and process resource.
Another one is pub files many times by partition, which may not so graceful and complex code .
I think the best practice is pub the whole configuration XML file but filtering it on pub side.
Is that possible?
Thank you very much!
Jason
Hi Jason,
If I understand you correctly, you want DDS to only send different parts of the same data to different subscribers. So, if you think of a piece of data being sent by a DataWriter as a message, you want subscribers to see different parts of that message.
If that's what you want, I'm afraid that DDS cannot do that.
So a "content-filter" is frankly the wrong nomenclature. Really it should be "content-based filter". And it's actually only a visible concept on the subscriber side (DataReaders are created with "ContentFilteredTopics"), application code on the publishing side wouldn't know anything about ContentFilteredTopics. Under the hood, Connext DDS will do the filtering on the publishing side if possible, and if not, it will filter on the receiving side. HOWEVER, Connext DDS uses the filter (fundamentally an boolean equation based on the values of the member elements of the data sample of a topic...aka, the "value" of the contents of a data sample") to decide whether or not a data value/sample should be delivered to the DataReader (that has been created with a ContentFilteredTopic).
If passing the data value through the filter returns true, then the data is delivered. If the filter returns false, the sample is not delivered. Again, Connext DDS will try to apply the filter in the publishing application before DDS sends it on the network (saving bandwidth if the sample is filtered out), but in certain circumstances, the filter cannot be applied in the publishing application and must be used after the sample is receive by the subscribing application to decide if to pass the received value to the user application (for example, if multicast is used to send the data).
Where ever the filter is applied, the entire data sample is received by a DataReader or not. Content filter does not mean that DDS can selectively only send a part of the data. The whole data sample is received or not.
When you wrote "partition", it was unclear if you are referring to an application-level concept or the Partition QosPolicy of DDS (which can be used to help implement data connectivity requirements of a system-specific concept of partition). In any case, it seems that what you have is a configuration information in XML format in which different applications will want different configuration information.
Your idea is to put all of the configuration into a single XML data sample, and wish that DDS can deliver different portions of the XML configuration to different subscribing applications. Again, that's not possible.
A possible design (up to you to determine the pros vs cons) is to use a single Topic to publish out the XML configuration information, however, your publishing application would publish different data samples for different "partitions" (not the DDS Partition QOS concept). This means, instead of publishing a monolithic single data sample that has all of the configurations for all of the participants, your application would need to segment and create different XML values that represents the configuration needed for different "partitions". In addition the the XML value (which I assume is a string), you would add a field representing a "partition". Then applications that subscribe to the configuration Topic, can do so with a ContentFilteredTopic based on the value of the "partition" field. So that applications would only receive the data samples that have the "partition" field set to the partition for which they "belong".
Assuming DDS can filter this on the sending side, bandwidth will be saved since data samples that don't match the "partition" of a subscriber won't be sent to the subscriber. However, if you can have multiple DataReaders in the same "partition" (again, this is not the DDS concept, but a user one), you may want to take advantage of the DataReader Transport Multicast QosPolicy which allows DDS to send a data sample only once on the network to be received by everyone (as opposed to the default of sending the same value repeatedly in case there are multiple subscribers). In case Multicast is configured to receive the data, DDS will perform the filtering on the receiving side, so that the application still only gets that data for the "partition" in which it is interested.
In addition, if you make the field of the Topic a "key" field, then
a) the filtering can be quite efficient since key fields are hashed so if the field type is a string, instead of a string compare, a numeric comparison is executed
b) you can take advantage of the Durability QOS and History QOS to configure the publishing application to store the last configuration value for each "partition" and automatically send that value to newly started applications for a partition
The data structure definition in IDL would be something like
struct ConfigType {
@key string partition; // the partition here is specified as a string, can also be an enumeration or any integer value
string<65535> config; // assuming that you want the configuration to be an XML-formatted string, need to specify max length or use unbounded strings
};
Thank you so much for your detailed explanation.
Yes, You're absolutely right.And my partition is the Partition QosPolicy of DDS.
So the best solution now is to separate configuration XML into segments by ConfigType and send them one by one?
Thank you!
Jason
So, yes to your question.
I don't think that using the Partition QOS is the best approach. This would require you to have muttiple DataWriters/DDSPublishers to send the data, one for each Partition.
If you use an extra field that has a value that specifies the "partition" and then use content-filter Topics on the subscriber side, your sending application would only need to have one datawriter/publisher, and then modify the field value to specify which "partition" that you want to send the value to.
--Howard
In my scenario, the partition plays more like a role of DDS domain and the IDL struct is defined by a standard UML model, so it's hard to add an extra field, like "partition".
I will have a try on both approach to find out which one is better.
Thank you very much.