Hi,
I have a question on multiple data writer scenarios:
Assuming there is a topic
struct Foo
{
unint32 a;
unint32 b;
}
Two data writers: A and B can update this topic. They both have to subscribe to the topic too in order to get the update from each other. Is the following scenario possible
1. A publishes a sample (a=10 and b=20)
2. B gets the sample ( a=10 and b=20)
3. A then publishes another sample ( a=11 and b=20)
3. Right before B receives the new sample, it needs to publish b=21. Since it hasn't received latest sample(a=11 and b=20), it ends up publishing (a=10 and b=21)
4. Now A gets confused since it just publishes a=11, but now the number goes back to 10.
Is this possible especially when the clocks of A and B are not in sync?
Regards,
Peter
Don't confuse data writers and data readers. The two applications will have each have a data writer and a data reader. If both applications want to publish the exact same data, using the concept of ownership is the preferred solution. There is a nice description of this by my colleague
https://community.rti.com/kb/how-do-i-implement-redundancy-rti-connext
Hi,
Thanks for the reply!
If the OWNERSHIP is set to be SHARED, is the scenario I described a concern? If yes, is it a good practice to create two separate topics, one for A and one for B?
Regards,
Peter
So, it's unclear what you want to happen. Given that both applications are publishing values for the same Topic, what do you want subscribers of that Topic to see as the "final" answer when there's a race condition?
The problem exists even without a Topic having 2 members which different applications are modifying different members. Say we have a Topic with the data below:
struct MyType {
long a;
};
If Application 1 sends a=1 and Application 2 sends a=2, "at the same time", what do applications who subscribe to the Topic receive. Well, in a distributed system, it's a race condition, some applications may receive packet containing 1 then the packet containing 2. Others may receive 2 then 1.
However, you can control how DDS presents received data to the user code. By using the DestinationOrder QoS Policy, you can configure DDS to either present the data as it is received (by default), so that one app sees a=1 and then a=2, and the other app sees a=2 and then a=1. Or if you use BY_SOURCE_TIMESTAMP, DDS will use the source timestamp (which is the time on of the publishing host when the data was sent) to determine what data to send.
No assumption of the synchronization of clocks is made by the logic. However, no guarantee of whose data an application gets is made either. What is being "guaranteed" is that all subscribing apps will all receive the same data sample as the "last" data sample if the writers stop sending data. It is possible that some subscribers won't receive all of the data sent by every publisher, but they will all receive the same last sample when the publishing apps stop sending data.
Example
Pub 1 sends Sample 1.1 (a=1, ts=0.01)
Pub 2 sends Sample 2.1 (a=2, ts=0.02)
(ts can be from 2 different unsynchronized clocks...doesn't matter, what matters is what is the value)
Sub 1 receives samples 1.1 and then 2.1
Sub 2 receives samlpes 2.1 and then 1.1
Default Processing is BY_RECEPTION_TIMESTAMP
Sub 1: Samples 1.1 and then 2.1 is provided to the user code. Last value a = 2
Sub 2: Samples 2.1 and then 1.1 is provided to the user code. Last value a = 1
Processing with DestinationOrder.kind = BY_SOURCE_TIMESTAMP
Sub 1: Samples 1.1 and then 2.1 is provided to the user code. Last value a = 2
Sub 2: Samples 2.1 is provided to the user code, Sample 1.1 is dropped, source ts < source ts of the last sample received, Last value a =2
So when using BY_SOURCE_TIMESTAMP, if data is received whose source timestamp is earlier than the source timestamp of the last data that was received...then that data is dropped and the user application will never see it.
You can control the scope of timestamp to be instance-based if your Topic is keyed.
But fundamentally, the question is, what did you want to happen in your case?
A sends (a=10, b=20), B receives (a=10, b=20), B sends (a=10, b=21), A sends (a=11, b=20)
What do you want to happen if the sequence above happens. There's nothing that can be done to prevent A from sending something before it receives what B sends...how is DDS/A to know that B has sent anything?
What can be done is to ensure that all subscribers get the same last value (a=10, and b=21) or (a=11, b=20).