From 3350f9cbf5d7b7c2e69a4c7b1713e1e9e78859c0 Mon Sep 17 00:00:00 2001 From: Sander van Harmelen Date: Thu, 19 Dec 2024 13:24:43 +0100 Subject: [PATCH] Rename auto_recreate_subscriptions to just recreate_subscriptions (#6) This is of course again a nitpick (also the last one), but I felt `auto_recreate_subscriptions` was a bit out of sync with the other options used (as they are all also doing something automatically), like `should_reconnect` and `recreate_monitored_items_chunk`. In addition I (tried to) reorder the used options a bit so they are both grouped and more or less in sync over places where a similar (or the same) list of options are used in order to try and make it easier to find things in the lists. While I like these micro improvements, I get that different people may have different preferences... --- opcua-client/src/builder.rs | 120 ++++++++++----------- opcua-client/src/config.rs | 94 ++++++++-------- opcua-client/src/session/connect.rs | 2 +- opcua-client/src/session/implementation.rs | 8 +- samples/client.conf | 2 +- 5 files changed, 112 insertions(+), 114 deletions(-) diff --git a/opcua-client/src/builder.rs b/opcua-client/src/builder.rs index 1fd1c78bb..8c1d1954a 100644 --- a/opcua-client/src/builder.rs +++ b/opcua-client/src/builder.rs @@ -158,33 +158,49 @@ impl ClientBuilder { self } - /// Sets the maximum outgoing message size in bytes. 0 means no limit. - pub fn max_message_size(mut self, max_message_size: usize) -> Self { - self.config.decoding_options.max_message_size = max_message_size; + /// Requested secure channel token lifetime, in milliseconds. + /// The channel will be renewed once 3/4 of the + /// lifetime has elapsed. Setting this too low is likely to cause issues. + pub fn channel_lifetime(mut self, channel_lifetime: u32) -> Self { + self.config.channel_lifetime = channel_lifetime; self } - /// Sets the maximum number of chunks in an outgoing message. 0 means no limit. - pub fn max_chunk_count(mut self, max_chunk_count: usize) -> Self { - self.config.decoding_options.max_chunk_count = max_chunk_count; + /// Sets the session retry limit. + /// + /// # Panics + /// + /// Panics if `session_retry_limit` is less -1. + pub fn session_retry_limit(mut self, session_retry_limit: i32) -> Self { + if session_retry_limit < 0 && session_retry_limit != -1 { + panic!("Session retry limit must be -1, 0 or a positive number"); + } + self.config.session_retry_limit = session_retry_limit; self } - /// Maximum size of each individual outgoing message chunk. - pub fn max_chunk_size(mut self, max_chunk_size: usize) -> Self { - self.config.decoding_options.max_chunk_size = max_chunk_size; + /// Initial time between retries when backing off on session reconnects. + pub fn session_retry_initial(mut self, session_retry_initial: Duration) -> Self { + self.config.session_retry_initial = session_retry_initial; self } - /// Maximum size of each incoming chunk. - pub fn max_incoming_chunk_size(mut self, max_incoming_chunk_size: usize) -> Self { - self.config.decoding_options.max_incoming_chunk_size = max_incoming_chunk_size; + /// Maximum time between retries when backing off on session reconnects. + pub fn session_retry_max(mut self, session_retry_max: Duration) -> Self { + self.config.session_retry_max = session_retry_max; self } - /// Maximum length in bytes of a string. 0 actually means 0, i.e. no string permitted. - pub fn max_string_length(mut self, max_string_length: usize) -> Self { - self.config.decoding_options.max_string_length = max_string_length; + /// Time between making simple Read requests to the server to check for liveness + /// and avoid session timeouts. + pub fn keep_alive_interval(mut self, keep_alive_interval: Duration) -> Self { + self.config.keep_alive_interval = keep_alive_interval; + self + } + + /// Maximum number of array elements. 0 actually means 0, i.e. no array permitted + pub fn max_array_length(mut self, max_array_length: usize) -> Self { + self.config.decoding_options.max_array_length = max_array_length; self } @@ -194,41 +210,33 @@ impl ClientBuilder { self } - /// Maximum number of array elements. 0 actually means 0, i.e. no array permitted - pub fn max_array_length(mut self, max_array_length: usize) -> Self { - self.config.decoding_options.max_array_length = max_array_length; + /// Sets the maximum number of chunks in an outgoing message. 0 means no limit. + pub fn max_chunk_count(mut self, max_chunk_count: usize) -> Self { + self.config.decoding_options.max_chunk_count = max_chunk_count; self } - /// Sets the session retry limit. - /// - /// # Panics - /// - /// Panics if `session_retry_limit` is less -1. - pub fn session_retry_limit(mut self, session_retry_limit: i32) -> Self { - if session_retry_limit < 0 && session_retry_limit != -1 { - panic!("Session retry limit must be -1, 0 or a positive number"); - } - self.config.session_retry_limit = session_retry_limit; + /// Maximum size of each individual outgoing message chunk. + pub fn max_chunk_size(mut self, max_chunk_size: usize) -> Self { + self.config.decoding_options.max_chunk_size = max_chunk_size; self } - /// Initial time between retries when backing off on session reconnects. - pub fn session_retry_initial(mut self, session_retry_initial: Duration) -> Self { - self.config.session_retry_initial = session_retry_initial; + /// Maximum size of each incoming chunk. + pub fn max_incoming_chunk_size(mut self, max_incoming_chunk_size: usize) -> Self { + self.config.decoding_options.max_incoming_chunk_size = max_incoming_chunk_size; self } - /// Maximum time between retries when backing off on session reconnects. - pub fn session_retry_max(mut self, session_retry_max: Duration) -> Self { - self.config.session_retry_max = session_retry_max; + /// Sets the maximum outgoing message size in bytes. 0 means no limit. + pub fn max_message_size(mut self, max_message_size: usize) -> Self { + self.config.decoding_options.max_message_size = max_message_size; self } - /// Time between making simple Read requests to the server to check for liveness - /// and avoid session timeouts. - pub fn keep_alive_interval(mut self, keep_alive_interval: Duration) -> Self { - self.config.keep_alive_interval = keep_alive_interval; + /// Maximum length in bytes of a string. 0 actually means 0, i.e. no string permitted. + pub fn max_string_length(mut self, max_string_length: usize) -> Self { + self.config.decoding_options.max_string_length = max_string_length; self } @@ -261,12 +269,6 @@ impl ClientBuilder { self } - /// Sets the session timeout period, in milliseconds. - pub fn session_timeout(mut self, session_timeout: u32) -> Self { - self.config.session_timeout = session_timeout; - self - } - /// Sets whether the client should ignore clock skew so the client can make a successful /// connection to the server, even when the client and server clocks are out of sync. pub fn ignore_clock_skew(mut self, ignore_clock_skew: bool) -> Self { @@ -282,28 +284,26 @@ impl ClientBuilder { self } - /// Session name - the default name to use for a new session - pub fn session_name(mut self, session_name: impl Into) -> Self { - self.config.session_name = session_name.into(); - self - } - - /// Requested secure channel token lifetime, in milliseconds. - /// The channel will be renewed once 3/4 of the - /// lifetime has elapsed. Setting this too low is likely to cause issues. - pub fn channel_lifetime(mut self, channel_lifetime: u32) -> Self { - self.config.channel_lifetime = channel_lifetime; - self - } - /// Automatically recreate subscriptions on reconnect, by first calling /// [`crate::Session::transfer_subscriptions`], then attempting to recreate /// subscriptions if that fails. /// /// Defaults to `true`. Note that if you disable this feature, you will need to /// handle cleanup of the subscriptions in the session yourself. - pub fn auto_recreate_subscriptions(mut self, auto_recreate_subscriptions: bool) -> Self { - self.config.auto_recreate_subscriptions = auto_recreate_subscriptions; + pub fn recreate_subscriptions(mut self, recreate_subscriptions: bool) -> Self { + self.config.recreate_subscriptions = recreate_subscriptions; + self + } + + /// Session name - the default name to use for a new session + pub fn session_name(mut self, session_name: impl Into) -> Self { + self.config.session_name = session_name.into(); + self + } + + /// Sets the session timeout period, in milliseconds. + pub fn session_timeout(mut self, session_timeout: u32) -> Self { + self.config.session_timeout = session_timeout; self } } diff --git a/opcua-client/src/config.rs b/opcua-client/src/config.rs index a59bdc4ac..18c77bde2 100644 --- a/opcua-client/src/config.rs +++ b/opcua-client/src/config.rs @@ -244,10 +244,13 @@ pub struct ClientConfig { pub(crate) preferred_locales: Vec, /// Identifier of the default endpoint pub(crate) default_endpoint: String, - /// User tokens - pub(crate) user_tokens: BTreeMap, /// List of end points pub(crate) endpoints: BTreeMap, + /// User tokens + pub(crate) user_tokens: BTreeMap, + /// Requested channel lifetime in milliseconds. + #[serde(default = "defaults::channel_lifetime")] + pub(crate) channel_lifetime: u32, /// Decoding options used for serialization / deserialization #[serde(default)] pub(crate) decoding_options: DecodingOptions, @@ -284,22 +287,17 @@ pub struct ClientConfig { #[serde(default = "defaults::min_publish_interval")] pub(crate) min_publish_interval: Duration, - /// Requested session timeout in milliseconds - #[serde(default = "defaults::session_timeout")] - pub(crate) session_timeout: u32, - /// Client performance settings pub(crate) performance: Performance, - /// Session name - pub(crate) session_name: String, - - /// Requested channel lifetime in milliseconds. - #[serde(default = "defaults::channel_lifetime")] - pub(crate) channel_lifetime: u32, /// Automatically recreate subscriptions on reconnect, by first calling /// `transfer_subscriptions`, then attempting to recreate subscriptions if that fails. - #[serde(default = "defaults::auto_recreate_subscriptions")] - pub(crate) auto_recreate_subscriptions: bool, + #[serde(default = "defaults::recreate_subscriptions")] + pub(crate) recreate_subscriptions: bool, + /// Session name + pub(crate) session_name: String, + /// Requested session timeout in milliseconds + #[serde(default = "defaults::session_timeout")] + pub(crate) session_timeout: u32, } impl Config for ClientConfig { @@ -480,6 +478,10 @@ mod defaults { true } + pub fn channel_lifetime() -> u32 { + 60_000 + } + pub fn session_retry_limit() -> i32 { SessionRetryPolicy::DEFAULT_RETRY_LIMIT as i32 } @@ -496,30 +498,26 @@ mod defaults { Duration::from_secs(10) } - pub fn max_failed_keep_alive_count() -> u64 { - 0 - } - - pub fn request_timeout() -> Duration { - Duration::from_secs(60) - } - - pub fn min_publish_interval() -> Duration { - Duration::from_millis(100) + pub fn max_array_length() -> usize { + opcua_types::constants::MAX_ARRAY_LENGTH } - pub fn publish_timeout() -> Duration { - Duration::from_secs(60) + pub fn max_byte_string_length() -> usize { + opcua_types::constants::MAX_BYTE_STRING_LENGTH } - pub fn session_timeout() -> u32 { - 60_000 + pub fn max_chunk_count() -> usize { + opcua_types::constants::MAX_CHUNK_COUNT } pub fn max_chunk_size() -> usize { 65535 } + pub fn max_failed_keep_alive_count() -> u64 { + 0 + } + pub fn max_incoming_chunk_size() -> usize { 65535 } @@ -528,32 +526,32 @@ mod defaults { opcua_types::constants::MAX_MESSAGE_SIZE } - pub fn max_chunk_count() -> usize { - opcua_types::constants::MAX_CHUNK_COUNT - } - pub fn max_string_length() -> usize { opcua_types::constants::MAX_STRING_LENGTH } - pub fn max_byte_string_length() -> usize { - opcua_types::constants::MAX_BYTE_STRING_LENGTH + pub fn request_timeout() -> Duration { + Duration::from_secs(60) } - pub fn max_array_length() -> usize { - opcua_types::constants::MAX_ARRAY_LENGTH + pub fn publish_timeout() -> Duration { + Duration::from_secs(60) + } + + pub fn min_publish_interval() -> Duration { + Duration::from_millis(100) } pub fn recreate_monitored_items_chunk() -> usize { 1000 } - pub fn channel_lifetime() -> u32 { - 60_000 + pub fn recreate_subscriptions() -> bool { + true } - pub fn auto_recreate_subscriptions() -> bool { - true + pub fn session_timeout() -> u32 { + 60_000 } } @@ -569,31 +567,31 @@ impl ClientConfig { ClientConfig { application_name: application_name.into(), application_uri: application_uri.into(), + product_uri: String::new(), create_sample_keypair: false, certificate_path: None, private_key_path: None, trust_server_certs: false, verify_server_certs: defaults::verify_server_certs(), - product_uri: String::new(), pki_dir, preferred_locales: Vec::new(), default_endpoint: String::new(), - user_tokens: BTreeMap::new(), endpoints: BTreeMap::new(), + user_tokens: BTreeMap::new(), + channel_lifetime: defaults::channel_lifetime(), + decoding_options: DecodingOptions::default(), session_retry_limit: defaults::session_retry_limit(), session_retry_initial: defaults::session_retry_initial(), session_retry_max: defaults::session_retry_max(), keep_alive_interval: defaults::keep_alive_interval(), + max_failed_keep_alive_count: defaults::max_failed_keep_alive_count(), request_timeout: defaults::request_timeout(), - min_publish_interval: defaults::min_publish_interval(), publish_timeout: defaults::publish_timeout(), - session_timeout: defaults::session_timeout(), - decoding_options: DecodingOptions::default(), + min_publish_interval: defaults::min_publish_interval(), performance: Performance::default(), + recreate_subscriptions: defaults::recreate_subscriptions(), session_name: "Rust OPC UA Client".into(), - max_failed_keep_alive_count: defaults::max_failed_keep_alive_count(), - channel_lifetime: defaults::channel_lifetime(), - auto_recreate_subscriptions: defaults::auto_recreate_subscriptions(), + session_timeout: defaults::session_timeout(), } } } diff --git a/opcua-client/src/session/connect.rs b/opcua-client/src/session/connect.rs index ec5f8b541..ac200c3ac 100644 --- a/opcua-client/src/session/connect.rs +++ b/opcua-client/src/session/connect.rs @@ -101,7 +101,7 @@ impl SessionConnector { } }; - if self.inner.auto_recreate_subscriptions { + if self.inner.recreate_subscriptions { self.inner.transfer_subscriptions_from_old_session().await; } diff --git a/opcua-client/src/session/implementation.rs b/opcua-client/src/session/implementation.rs index 1c1ef50fc..59dde4b54 100644 --- a/opcua-client/src/session/implementation.rs +++ b/opcua-client/src/session/implementation.rs @@ -59,6 +59,8 @@ pub struct Session { pub(super) request_timeout: Duration, pub(super) publish_timeout: Duration, pub(super) recreate_monitored_items_chunk: usize, + pub(super) recreate_subscriptions: bool, + pub(super) should_reconnect: AtomicBool, pub(super) session_timeout: f64, /// Reference to the subscription cache for the client. pub subscription_state: Mutex, @@ -67,8 +69,6 @@ pub struct Session { pub(super) monitored_item_handle: AtomicHandle, pub(super) trigger_publish_tx: tokio::sync::watch::Sender, decoding_options: DecodingOptions, - pub(super) should_reconnect: AtomicBool, - pub(super) auto_recreate_subscriptions: bool, pub(super) encoding_context: Arc>, } @@ -133,6 +133,8 @@ impl Session { session_timeout: config.session_timeout as f64, publish_timeout: config.publish_timeout, recreate_monitored_items_chunk: config.performance.recreate_monitored_items_chunk, + recreate_subscriptions: config.recreate_subscriptions, + should_reconnect: AtomicBool::new(true), subscription_state: Mutex::new(SubscriptionState::new( config.min_publish_interval, publish_limits_watch_tx.clone(), @@ -142,8 +144,6 @@ impl Session { publish_limits_watch_tx, trigger_publish_tx, decoding_options, - should_reconnect: AtomicBool::new(true), - auto_recreate_subscriptions: config.auto_recreate_subscriptions, encoding_context, }); diff --git a/samples/client.conf b/samples/client.conf index 5b9b2813b..4f87d09a8 100644 --- a/samples/client.conf +++ b/samples/client.conf @@ -71,4 +71,4 @@ performance: recreate_monitored_items_chunk: 1000 session_name: Rust OPC UA Client channel_lifetime: 60000 -auto_recreate_subscriptions: true +recreate_subscriptions: true