From fd977fb70bbd8ae205a85daacfe42e72006850b6 Mon Sep 17 00:00:00 2001 From: "ChenYing Kuo (CY)" Date: Sat, 11 Jan 2025 18:27:59 +0800 Subject: [PATCH] actions/get_result has a different default timeout. (#372) Signed-off-by: ChenYing Kuo Co-authored-by: Julien Enoch --- DEFAULT_CONFIG.json5 | 7 +++-- zenoh-plugin-ros2dds/src/config.rs | 48 ++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/DEFAULT_CONFIG.json5 b/DEFAULT_CONFIG.json5 index f330cde..5498efb 100644 --- a/DEFAULT_CONFIG.json5 +++ b/DEFAULT_CONFIG.json5 @@ -125,7 +125,10 @@ //// //// queries_timeout: Timeouts configuration for various Zenoh queries. - //// Each field is optional. If not set, the 'default' timeout (5.0 seconds by default) applies to all queries. + //// Each field is optional. If not set, the 'default' timeout (5.0 seconds by default) applies to all queries, + //// except for actions' get_result that is by default configured with a larget timeout (300.0 seconds) + //// to support actions that last a long time. + //// Refer to https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/issues/369#issuecomment-2563725619 //// Each value can be either a float in seconds that will apply as a timeout to all queries, //// either a list of strings with format "=" where: //// - "regex" is a regular expression matching an interface name @@ -142,7 +145,7 @@ // actions: { // send_goal: 1.0, // cancel_goal: 1.0, - // get_result: [".*long_mission=3600", ".*short_action=10.0"], + // get_result: [".*long_mission=3600", ".*short_action=10.0", ".*=300"], // } // }, diff --git a/zenoh-plugin-ros2dds/src/config.rs b/zenoh-plugin-ros2dds/src/config.rs index a8e2c54..30bf504 100644 --- a/zenoh-plugin-ros2dds/src/config.rs +++ b/zenoh-plugin-ros2dds/src/config.rs @@ -25,6 +25,10 @@ pub const DEFAULT_RELIABLE_ROUTES_BLOCKING: bool = true; pub const DEFAULT_TRANSIENT_LOCAL_CACHE_MULTIPLIER: usize = 10; pub const DEFAULT_DDS_LOCALHOST_ONLY: bool = false; pub const DEFAULT_QUERIES_TIMEOUT: f32 = 5.0; +// In the ROS 2 action, get_result is sent out first and then wait for the result. +// It will cause the action client never complete, so we need a larger timeout. +// Refer to https://github.com/eclipse-zenoh/zenoh-plugin-ros2dds/issues/369#issuecomment-2563725619 +pub const DEFAULT_ACTION_GET_RESULT_TIMEOUT: f32 = 300.0; pub const DEFAULT_WORK_THREAD_NUM: usize = 2; pub const DEFAULT_MAX_BLOCK_THREAD_NUM: usize = 50; @@ -59,7 +63,7 @@ pub struct Config { pub shm_enabled: bool, #[serde(default = "default_transient_local_cache_multiplier")] pub transient_local_cache_multiplier: usize, - #[serde(default)] + #[serde(default = "default_queries_timeout")] pub queries_timeout: Option, #[serde(default = "default_reliable_routes_blocking")] pub reliable_routes_blocking: bool, @@ -170,23 +174,16 @@ impl Config { pub fn get_queries_timeout_action_get_result(&self, ros2_name: &str) -> Duration { match &self.queries_timeout { Some(QueriesTimeouts { - default, - actions: Some(at), - .. + actions: Some(at), .. }) => { for (re, secs) in &at.get_result { if re.is_match(ros2_name) { return Duration::from_secs_f32(*secs); } } - Duration::from_secs_f32(*default) + Duration::from_secs_f32(DEFAULT_ACTION_GET_RESULT_TIMEOUT) } - Some(QueriesTimeouts { - default, - actions: None, - .. - }) => Duration::from_secs_f32(*default), - _ => Duration::from_secs_f32(DEFAULT_QUERIES_TIMEOUT), + _ => Duration::from_secs_f32(DEFAULT_ACTION_GET_RESULT_TIMEOUT), } } } @@ -194,7 +191,7 @@ impl Config { #[derive(Deserialize, Debug, Serialize)] #[serde(deny_unknown_fields)] pub struct QueriesTimeouts { - #[serde(default = "default_queries_timeout")] + #[serde(default = "default_queries_timeout_default")] default: f32, #[serde( default, @@ -208,7 +205,7 @@ pub struct QueriesTimeouts { serialize_with = "serialize_vec_regex_f32" )] services: Vec<(Regex, f32)>, - #[serde(default)] + #[serde(default = "default_actions_timeout")] actions: Option, } @@ -228,7 +225,7 @@ pub struct ActionsTimeouts { )] cancel_goal: Vec<(Regex, f32)>, #[serde( - default, + default = "default_actions_get_result_timeout", deserialize_with = "deserialize_vec_regex_f32", serialize_with = "serialize_vec_regex_f32" )] @@ -403,10 +400,31 @@ fn default_domain() -> u32 { } } -fn default_queries_timeout() -> f32 { +fn default_queries_timeout() -> Option { + Some(QueriesTimeouts { + default: default_queries_timeout_default(), + transient_local_subscribers: Vec::new(), + services: Vec::new(), + actions: default_actions_timeout(), + }) +} + +fn default_queries_timeout_default() -> f32 { DEFAULT_QUERIES_TIMEOUT } +fn default_actions_timeout() -> Option { + Some(ActionsTimeouts { + send_goal: Vec::new(), + cancel_goal: Vec::new(), + get_result: default_actions_get_result_timeout(), + }) +} + +fn default_actions_get_result_timeout() -> Vec<(Regex, f32)> { + vec![(Regex::new(".*").unwrap(), DEFAULT_ACTION_GET_RESULT_TIMEOUT)] +} + fn deserialize_path<'de, D>(deserializer: D) -> Result>, D::Error> where D: Deserializer<'de>,