locka99 / opcua

A client and server implementation of the OPC UA specification written in Rust
Mozilla Public License 2.0
496 stars 131 forks source link

Limits With Subscriptions Server? #97

Open morphace opened 3 years ago

morphace commented 3 years ago

When I try to set the queue size or sample interval, it seems the opcua-server is sending much lower revised values (queue size becomes 10, if I try to set 100).

The background is that I'm trying to sucbscribe to values that change every 10ms (actually I would like to go down to 1ms).

Is that supposed to work? Why is the sever limiting the queue size to 10?

I can see that in subscription.rs:

                                let revised_sampling_interval = monitored_item.sampling_interval();
                                let revised_queue_size = monitored_item.queue_size() as u32;

Instead of using the values from item_to_create

locka99 commented 3 years ago

At the moment there are constants defined in the server\src\lib.rs here:

/// The polling interval in millis on subscriptions and monitored items. The more
/// fine-grained this is, the more often subscriptions will be checked for changes. The minimum
/// publish interval cannot be less than this.
pub const SUBSCRIPTION_TIMER_RATE_MS: u64 = 100;
/// Minimum publishing interval for subscriptions
pub const MIN_PUBLISHING_INTERVAL: f64 = (SUBSCRIPTION_TIMER_RATE_MS as f64) / 1000.0;
/// Minimum sampling interval on monitored items
pub const MIN_SAMPLING_INTERVAL: f64 = (SUBSCRIPTION_TIMER_RATE_MS as f64) / 1000.0;
/// Maximum data change queue allowed by clients on monitored items
pub const MAX_DATA_CHANGE_QUEUE_SIZE: usize = 10;

This is why the settings are revised. You could fork the source to modify them to another value. I do expose some server settings through a ServerLimits section of the configuration / builder and queue size can be overridden but not the min sampling intervals, so I may expose these too. Note I haven't tried with super fast polling rates so there might be latencies in there.

morphace commented 3 years ago

Thanks a lot for the hint! I can see minimum sampling interval and publishing interval (ms) being adjustable in the configuration:

        let min_publishing_interval_ms = config.limits.min_publishing_interval * 1000.0;
        let min_sampling_interval_ms = config.limits.min_sampling_interval * 1000.0;

On the other hand, the values returned to the client (at least the sampling interval) are set using the constants in lib.rs (via the sanitize method).

    fn sanitize_sampling_interval(requested_sampling_interval: f64) -> f64 {
        if requested_sampling_interval < 0.0 {
            // From spec "any negative number is interpreted as -1"
            // -1 means monitored item's sampling interval defaults to the subscription's publishing interval
            -1.0
        } else if requested_sampling_interval == 0.0
            || requested_sampling_interval < constants::MIN_SAMPLING_INTERVAL
        {
            constants::MIN_SAMPLING_INTERVAL
        } else {
            requested_sampling_interval
        }
    }

When I go down with the settings, for example:

I can see that values are coming more or less in sequence (with some missing in between), but the # of values coming are very different (I'd expect to receive 10 values per publish in average, but it's 80, 19, 38, 142, ...).

Also I receive frequently a message on the server side: "Too many publish requests 2 for capacity 2".

Actually, I'd like to go down with the polling interval even further (we're developing for the machine industry and there you sometimes need to monitor values that change very frequently).

I think a Rust based opcua framework should be capable of being on par with C/C++? So I guess it's about optimization here...

I'll experiment here, but maybe you have some idea what to improve, or maybe I'm simply wrong...

morphace commented 3 years ago

Hi, any ideas?

locka99 commented 3 years ago

Yes I think the sanitize should use the configured values. Let me check how complex it is to change that and if its easy I'll do so.

locka99 commented 3 years ago

I've checked in changes to ensure the sanitize functions use the config settings

AiyionPrime commented 2 months ago

Hey there :) I'm glad you already thought about decreasing this hardcoded? limit. Is there anything I can do to make it configurable? As first step I'd like to be able to configure it in the ms range.