Frequently Asked Questions
This FAQ is based on the captured interactions on Github (related to both open as well as closed issues) and as such includes reference(s) to Github for more details related to the posed questions (and/or answers)
- Frequently Asked Questions
- API
- Patterns
- Best Practices
- DataModel / IDL
- Concepts
- What is the difference between read() and take()?
- How do I assure that all subscribers get the data from a short-lived publisher?
- (Writer-)History QoS KEEP_ALL doesn't result in late-joining reader(s) to receive the data
- How to communicate between DDS-domains?
- Is DDS useful for intermittent local communications without a fixed network?
- What are the semantics behind on_data_available?
- Performance
- Language Support
- Configuration
API
How do I specify a domain id?
There's some confusion w.r.t. the multiple ways to specify a domain id for Cyclone DDS.
Answer
- When specifying DDS_DOMAIN_DEFAULT upon creating a participant, the value as specified in the configuration (pointed to by the CYCLONEDDS_URI env. variable) will be used or 0 if not specified there.
- Not hardcoding the domain_id is seen as good practice yet its (now) also allowed to specify the (now default) value 'any' in the configuration which implies that a (or better any) domain id can be used in dds_create_participant()
See also
Patterns
How do I filter out 'self-sent' data?
Answer
- Set the
IgnoreLocal
QoS on your reader to discard any samples written by readers local to your publisher or participant scope. - The publication_handle can be checked on equality with the one returned by the get_instance_handle() on the writer-side.
- Use a ContentFilter to check the publisher id on the sample info.
See also
Best Practices
A take()
operation returns no data?
A take() in combination with TRANSIENT_LOCAL
QoS and BEST_EFFORT
reliability sometimes returns no data.
Answer
- Proper
TRANSIENT_LOCAL
durability-behavior requiresRELIABLE
delivery so the use-case is actually a anti-pattern - Note that the (re-)used pingpong example is messy w.r.t. either data-arrival or handling a signal could trigger the waitset (where in the latter case, no data would be returned)
See also
DataModel / IDL
What IDL is supported?
Answer
- See this guide on what is supported.
See also
What characters are allowed for topic-names?
Answer
- Only alphanumeric characters, '/' and '_' are allowed in topic-names
- Using a hyphen ('-') in a topic-name isn't accepted
- Contrary to the DDS spec (https://www.omg.org/spec/DDS/1.4/PDF) somehow both Cyclone DDS and OpenSpliceDDS support "_" rather than "-" as the spec prescribes
- An open question is: will/can we ever correct this and also: does this impact interoperability with other DDS implementations where topics with a "-" in the name might 'emerge' ?
See also
Concepts
What is the difference between read()
and take()
?
When looking at the examples, its unclear what the difference between them is and when to use one or the other
Answer
read()
is non-destructive meaning you can read the data again (as it remains in your reader-history) whereastake()
actually removes the 'taken' samples from that history- Typical usecases: when exploiting DDS as a shared-dataspace that (often) captures shared-state, a
read()
operation is appropriate to access the most recent state whereas when using DDS for pub/sub event-distribution thetake()
operation is more appropriate
See also
How do I assure that all subscribers get the data from a short-lived publisher?
When starting many subscribers of the HelloWorld example, not all get all published data
Answer
- By default, data is volatile meaning that when data is published/written before subscribers/readers are present, data won't be delivered
- Multiple reasons/remedies can be identified for this 'seeming data-loss': (1) the writer may be gone already before the reader emerges, remedy is exploiting
TRANSIENT
QoS for the data, (2) as discovery takes time, some data might already be published before the match between publisher/subscriber is discovered (even when both are started at the same time), remedy is to exploit 'endpoint-awareness' as provided bydds_get_publication_matched_status()
and wait in the publisher until the current_count equals the number of required/expected subscribers
See also
(Writer-)History QoS KEEP_ALL
doesn't result in late-joining reader(s) to receive the data
The (in the OMG-spec) specified KEEP_ALL
behavior seems to suggest that data is kept available for (later) delivery
Answer
For preserving published data for late-joining subscribers, the DURABILITY
QoS should be used (that works in conjuction with HISTORY
but isn't the same)
History
andDurability
are orthogonal concepts meaning thatKEEP_ALL
writer-history allows for a system 'in steady state' (in this case relating to existing readers) to 'eventually' deliver all samples from that writer-history to the history-cache of such an EXISTING reader. If on the other hand, data needs to be preserve for 'late-joining' readers, Durability features of DDS can be exploited (i.e.TRANSIENT_LOCAL
orTRANSIENT
QoS) to assure that such non-volatile data will be preserved and delivered to late-joining NEW readers (and in case ofTRANSIENT
data even if the publisher/writer of that data has already 'gone', noting thatTRANSIENT
QoS is still under development as of feb'22)
See also - cyclonedds#49
How to communicate between DDS-domains?
Answer
Cyclone DDS relies on Zenoh for that
- note that the question was asked in the ROS2 context which doesn't exploit the full DDS feature-set
- on each to-be-connected DDS domain a 'Zenoh bridge for DDS' can be deployed to bridge those two domains
See also
Is DDS useful for intermittent local communications without a fixed network?
This is useful to cases related to mobile devices that regularly go in and out of range
Answer
- For such use-cases, the combination of Eclipse’s Cyclone DDS and Zenoh products is suggested
- Sister project Zenoh explicitly targets dynamic connectivity and allows for transparent integration with an (otherwise) DDS-based system
See also
What are the semantics behind on_data_available
?
- It seems that on_data_available is triggered not just on actual new data arriving
Answer
- the
on_data_available
callback applies to both data as well as (instance-lifecycle)meta-data - following an on_data_available callback, a
read
(ortake
) will return either valid data (when new data arrived) or an invalid-sample to convey a lifecycle change related to the writer (typically for an empty instance i.e. one for which the data was already ‘taken’ by a previous call-back response
See also
Performance
Why are there huge latency outliers when sending huge samples ?
When sending 1MB samples on a 'standard' Ubuntu distro, latencies can spike from a typical 2 milliseconds towards 150 milliseconds
Answer
- Although Cyclone DDS 'asks' the operating system for a 1 megabyte socket-receive-buffer, in many cases it will give out a smaller buffer and thus requires the user to configure a higher allowed maximum receive-buffer-size
- Inspecting /proc/sys/net/core/rmem_max (on Linux) typically shows that such a maximum is insufficient for the intended sample-sizes and thus needs to be 'upped' i.e. using sysctl -w net.core.rmem_max=
See also
Language Support
Is 'Rust' an available language binding?
As Cyclone DDS is about the only open source DDS implementation written in 'C', it should (at least theoretically) be possible to create a 'Rust' binding on-top of it
Answer
- At the time of asking (aug/2020), there was an initiative to add an open source Rust-binding to Cyclone DDS
- See below that current (jan'22) version is 0.1.2 with last update in sept'20
See also
Is 'C#' an available language binding?
Answer
- At time of writing (august/2022) there is a C# language binding in the works by ZettaScale Technology.
Configuration
How do I use multiple (network) partitions in a custom profile?
Answer
- Cyclone DDS allows you to map logical DDS-partitions on physical ‘network-partitions’ (typically multicast-groups)
- Although the question was driven by reducing discovery, the below reference still contains a nice write-up on how to exploit network-partitions in Cyclone DDS
See also - cyclonedds#883
How do I configure multiple network interfaces?
Answer
- Automatic routing might prevent correct communication in case of multiple configured interfaces
- Setting the ‘General/DontRoute’ config-option typically prevents the issue reported here
- Multi-homing and routing is slated for a ‘deep-dive’ topic as its likely to pop up regularly in more complex setups
See also