Quality of Service

Quality Of Service is a way to configure system, and to make a contract between readers and writers of the expected behavior. During discovery, participants interchange Quality of Service information of each entity they manage. For any given topic, its readers and writers can start communicating if their Quality of Service is compatible. Compatibility of Quality of Service is presented with request-offer(RxO) semantics, where writers 'offer' Quality of Service and readers 'request' for it.

Deadline

Deadline QoS is used to make a contract between reader and writer of how frequently each instance is to be updated. If a reader detects that deadline has been missed, its CommunicationListeners will be notified of this fact. Likewise, udds DataWriter internally monitors that writers fulfill the deadline contract applications has made, and notifies CommunicationListeners of failures.

Deadline QoS between reader and writer is compatible if

 offered.deadline_period <= requested.deadline_period

Destination Order

This QoS policy controls how readers determine the order of Samples from multiple writers. If the kind is BY_RECEPTION_TIMESTAMP, the latest received value for the instance should be kept. BY_SOURCE_TIMESTAMP indicates that the timestamp set by the writers should be considered instead. Using BY_SOURCE_TIMESTAMP ensures that every subscriber in the system will end up having the same latest value for the instance.

Destination order QoS between reader and writer is compatible if

 offered.kind >= requested.kind

where BY_RECEPTION_TIMESTAMP < BY_SOURCE_TIMESTAMP

During reception, jRTPS sets timestamp of the Sample to system time if kind is BY_RECEPTION_TIME or writer does not provide timestamp even though it should.

Durability

Durability QoS is used to control how historical data is made available to readers. If VOLATILE kind is used, readers will not get any historical data. A reader will start getting samples only after reader and writer has been matched. jRTPS writers checks durability of reader during matching. If kind is VOLATILE, writer will mark reader as received all the samples so far. In all other cases, writer will notify readers of the changes available.

Setting Durability of udds DataWriters to a kind greater than TRANSIENT_LOCAL has no effect other than making a difference during QoS compatibility checking.

Durability QoS between reader and writer is compatible if

 offered.kind >= requested.kind

where VOLATILE < TRANSIENT_LOCAL < TRANSIENT < PERSISTENT

Liveliness

Every RTPS writer is expected to support liveliness protocol. Liveliness QoS is used to setup liveliness behavior of writers.

By using Liveliness kind AUTOMATIC, udds Participant will automatically refresh liveliness of its writers periodically based on lease_duration. If MANUAL_BY_PARTICIPANT kind is used, application is expected to refresh liveliness of its writers by calling Participant.assertLiveliness(). MANUAL_BY_TOPIC kind is used when each writer needs to individually call DataWriter.assertLiveliness()

Liveliness QoS between reader and writer is compatible if

 offered.kind >= requested.kind
 offered.lease_duration <= requested.lease_duration

where AUTOMATIC < MANUAL_BY_PARTICIPANT < MANUAL_BY_TOPIC

Reliability

Reliability QoS determines how samples are communicated from writers to readers. RELIABLE kind causes RTPS entities to exchange HeartBeat and AckNack messages. I.e. writers advertise what samples are available and readers will report back what samples they have received, and what are still missing. By using these messages, writers can eventually communicate all the changes in correct order to readers. When BEST_EFFORT kind is used, writers just sends samples to readers. That is the only promise writer makes about delivery of messages. Samples might be lost during transmission, or reader might decide to drop samples before it passes them to application.

Reliability QoS between reader and writer is compatible if

 offered.kind >= requested.kind

where BEST_EFFORT < RELIABLE

TimeBasedFilter

Time based filter is used to restrict reception of samples at reader to rate specified with minimum_separation. When a sample arrives at reader, and minimum_separation has not elapsed since previous sample, reader will discard that sample. The specification also says that last sample of writer should be delivered, if writer stops sending samples for period "long" compared to minimum_separation, and latest sample was filtered out by TimeBasedFilter.

TimeBasedFilter must be consistent with deadline QoS policy, so that

 deadline >= minimum_separation

Quality of Service - uDDS

Not all the Quality of Service defined in DDS specification is mandatory from the RTPS point of view. RTPS is about transmission. But DDS specifies a bunch of more QoS settings. While jRTPS tries to be 100% compatible with RTPS specification, uDDS makes no such promise to DDS specification. This section is about those settings, and how they are supported by uDDS-1.5.1.

Partition

Partitions are used to create logical isolation of entities, whereas domain physically isolates entities from each other. An entity should not communicate with its counterpart, unless they have a matching partition. An entity tells which partitions it is connected to by using Partition QoS policy. This policy contains an array of Strings, each representing a partition name. These partition names are transferred to remote entities during discovery.

Partition names can contain regular expressions. DDS specification says that two partitions should not be matched if they both contain regular expressions. uDDS partition checking is more flexible than this restriction; it allows partitions to match if both partition names contain regular expressions and they match each other in one way or another. For example "part.*" will match "partition.*"

Note, that other implementations might not behave this way and might result in communication not to be established. For this reason, one should be careful when using regular expressions in partition names.

History

This Quality of Service controls how the history cache is maintained by an Entity.

 kind = KEEP_LAST | KEEP_ALL
 depth = <int>

DDS specification states that if KEEP_ALL kind is used, writer should block if Reliability is set to RELIABLE and Samples would be lost by a write operation. KEEP_LAST kind is used when service will try to maintain and deliver only the depth number of samples. In this case, writer is allowed to drop oldest samples, even if it haven't been sent to readers.

udds supports only KEEP_LAST kind, i.e. writers will never block. In the DataReader, History QoS behaves similarly.

Note, that this means that DataReader might miss some samples, if the reader does not read the samples quick enough. By using SampleListener, one can be sure that DataReader gets all the samples delivered to application, even if they are removed by history cache. For DataWriter, this means that if DataWriter writes Samples quicker than it can deliver them to Readers, not all the readers might end up having all the samples.

Note also, that History QoS does not follow RxO semantics. I.e. Reader does not know how the writers history cache is configured. Nor can reader enforce writer to use either of the kinds.

Resource Limits

Resource limits is used to provide means to control resource usage of an Entity. DDS specification defines following attributes to control resource usage: max_instances, max_samples_per_instance, max_samples. These attributes must be defined consistently, so that

 max_samples >= max_samples_per_instance
 history.depth <= max_samples_per_instance

udds supports all the settings above. When any of the limits is reached, an OutOfResources exception is thrown. On reader side, resource limits are checked when Samples arrive from the network. Limits are thus checked by the network receiver thread, and application is therefore not aware of the resource limit problem.

UserData, GroupData, TopicData

These QoS policies allow applications to pass arbitrary byte array to remote entities. uDDS supports adding of these policies to QoS, and thus make remote entities aware of them. However, by default uDDS entities cannot read the QoS policy values of remote entity. If one needs to read those values, one can add a CommunicationListener to entity, and get the Quality Of Service when entities are matched.

DataRepresentation, TypeConsistencyEnforcement

These two QoS policies are defined in X-Types documentation. For the DataRepresentation, only XCDR_DATA_REPRESENTATION is supported. Setting the requested value to anything else results in incompatible QoS.

For the TypeConsistencyEnforcement, it is recognized, but not handled in any way.

Lifespan

Lifespan QoS policy is used to automatically remove samples from history cache of an entity. Intention of this policy is to remove samples, that becomes 'stale' after given time.

RTPS specification says that strict reliable communication requires that a sample cannot be removed until all the readers have acknowledged the reception of sample. uDDS writer cache does not check this, which makes udds writers not to be strict reliable if using Lifespan QoS policy.

At reader side, when a sample arrives it is 'tagged' with an expiration time, which is calculated using writers Lifespan QoS policy.

Ownership, OwnershipStrength

These policies are used to provide a concept of ownership of an instance. Ownership kind SHARED is used when every writer is treated equal, and every writer can make changes to history cache of a reader. With ownership kind EXCLUSIVE, a Sample gets written into readers history cache only if the writer is the owner of the instance, or writer is stronger than owner of the instance. In this case the stronger writer claims ownership of the Instance. A writer may loose ownership of instances it owns. This may happen if writer fails to assert its liveliness, or writer fails to fulfill deadline contract made with reader.

DDS Specification also says that if two equally strong writers exists in the system, service should pick one or the other. And all the readers should pick the same writer throughout the system as the owner. In practice, this is impossible to guarantee, as different vendors may choose differently. uDDS readers choose ownership by comparing Guids of the writers

Ownership QoS between reader and writer is compatible if

 offered.kind == requested.kind