opc-ua-client
opc-ua-client copied to clipboard
Published values out of order
We have been doing some stress testing with rapid updates from an OpcUA server. In our application, notifications are occassionally generated out of sequence. I am pretty sure that the following code in ClientSessionChannel.cs
is causing a problem:
private async Task StateMachineAsync(CancellationToken token = default)
{
var tasks = new[]
{
PublishAsync(token),
PublishAsync(token),
PublishAsync(token),
};
await Task.WhenAll(tasks).ConfigureAwait(false);
}
By starting the function PublishAsync
three times, there is a random element in how the responses from the OpaUA server are posted into the notification queue. If two updates are handled in different instances of the PublishAsync
function, the order in which they are posted to the notification queue is indeterminate.
If I comment out two of the calls to PublishAsync, so that there is only one loop generating publish requests, then they are always handled in the correct order.
By the way, if the responses are handled out of order, this will probably mean that the acknowledgements are sent to the server out of order. This doesn't seem good, but I'm not sure if it is critical.
My question is, what is the motivation for starting PublishAsync
three times? What problem does it solve?
Thanks for identifying the problem. The motivation for calling Publish three times is to follow the OPC recommendation of:
"Especially in high latency networks, the Client may wish to pipeline Publish requests to ensure cyclic reporting from the Server. Pipelining involves sending more than one Publish request for each Subscription before receiving a response. For example, if the network introduces a delay between the Client and the Server of 5 seconds and the publishing interval for a Subscription is one second, then the Client will have to issue Publish requests every second instead of waiting for a response to be received before sending the next request."
I realize now that the multiple tasks can complete out of order, so I should only use one task. One day, a clever person may show me how to pipeline in way that uses a single task.