From 7a395918bf281864a2df137ea3c873ae5f5c3b27 Mon Sep 17 00:00:00 2001 From: Einar Omang Date: Tue, 7 Jan 2025 21:00:38 +0100 Subject: [PATCH] Workaround for browser future not being Send This is incredibly hard to diagnose, because the compiler error is useless. --- lib/tests/integration/browse.rs | 22 +++++++++++++++------- opcua-client/src/session/retry.rs | 7 ++++++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/tests/integration/browse.rs b/lib/tests/integration/browse.rs index 5ac6121a8..04a95a9d3 100644 --- a/lib/tests/integration/browse.rs +++ b/lib/tests/integration/browse.rs @@ -617,20 +617,28 @@ async fn test_recursive_browser() { .is_some()); } +// Test that the future returned by `browser.run...` is `Send` +fn assert_send(v: R) -> R { + v +} + #[tokio::test] // Hit the same node multiple times. async fn test_recursive_browser_multi_hit() { let (_tester, _nm, session) = setup().await; let filter = BrowseFilter::new(BrowseDirection::Forward, ReferenceTypeId::References, true); + let to_browse = vec![filter.new_description_from_node(ObjectId::TypesFolder.into())]; - let res = session - .browser() - .max_concurrent_requests(3) - .handler(filter) - .run_into_result(to_browse) - .await - .unwrap(); + let res = assert_send( + session + .browser() + .max_concurrent_requests(3) + .handler(filter) + .run_into_result(to_browse), + ) + .await + .unwrap(); assert_eq!(4228, res.nodes.len()); diff --git a/opcua-client/src/session/retry.rs b/opcua-client/src/session/retry.rs index 3988c2398..b6959ef01 100644 --- a/opcua-client/src/session/retry.rs +++ b/opcua-client/src/session/retry.rs @@ -1,5 +1,6 @@ use std::time::Duration; +use futures::FutureExt; use opcua_types::StatusCode; use crate::retry::ExponentialBackoff; @@ -138,7 +139,11 @@ impl Session { ) -> Result { loop { let next_request = request.clone(); - match next_request.send(&self.channel).await { + // Removing `boxed` here causes any futures calling this to be non-send, + // due to a compiler bug. Look into removing this in the future. + // TODO: Check if tests compile without this in future rustc versions, especially + // if https://github.com/rust-lang/rust/issues/100013 is closed. + match next_request.send(&self.channel).boxed().await { Ok(r) => break Ok(r), Err(e) => { if let Some(delay) = policy.get_next_delay(e) {