From b87975300bcdb0b1020bd778f18d8b0812e413c1 Mon Sep 17 00:00:00 2001
From: Dmitrii Ubskii <18616863+dmitrii-ubskii@users.noreply.github.com>
Date: Fri, 8 Nov 2024 14:23:51 +0000
Subject: [PATCH 1/3] add timeout to channel builder

---
 rust/src/common/error.rs               |  4 ++++
 rust/src/connection/network/channel.rs | 14 +++++++++++---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/rust/src/common/error.rs b/rust/src/common/error.rs
index d6fb3908f0..2c226de5ec 100644
--- a/rust/src/common/error.rs
+++ b/rust/src/common/error.rs
@@ -74,6 +74,8 @@ error_messages! { ConnectionError
         23: "Invalid URL '{address}': missing port.",
     AddressTranslationMismatch { unknown: HashSet<Address>, unmapped: HashSet<Address> } =
         24: "Address translation map does not match the server's advertised address list. User-provided servers not in the advertised list: {unknown:?}. Advertised servers not mapped by user: {unmapped:?}.",
+    ConnectionTimedOut =
+        25: "Connection to the server timed out."
 }
 
 error_messages! { InternalError
@@ -196,6 +198,8 @@ impl From<Status> for Error {
             Self::Connection(ConnectionError::ServerConnectionFailedStatusError { error: status.message().to_owned() })
         } else if status.code() == Code::Unimplemented {
             Self::Connection(ConnectionError::RPCMethodUnavailable { message: status.message().to_owned() })
+        } else if status.code() == Code::Cancelled && status.message() == "Timeout expired" {
+            Self::Connection(ConnectionError::ConnectionTimedOut)
         } else {
             Self::from_message(status.message())
         }
diff --git a/rust/src/connection/network/channel.rs b/rust/src/connection/network/channel.rs
index efe852086d..ec526d64d3 100644
--- a/rust/src/connection/network/channel.rs
+++ b/rust/src/connection/network/channel.rs
@@ -17,7 +17,10 @@
  * under the License.
  */
 
-use std::sync::{Arc, RwLock};
+use std::{
+    sync::{Arc, RwLock},
+    time::Duration,
+};
 
 use tonic::{
     body::BoxBody,
@@ -49,8 +52,13 @@ impl GRPCChannel for PlainTextChannel {}
 
 impl GRPCChannel for CallCredChannel {}
 
+const TIMEOUT: Duration = Duration::from_secs(60);
+
 pub(super) fn open_plaintext_channel(address: Address) -> PlainTextChannel {
-    PlainTextChannel::new(Channel::builder(address.into_uri()).connect_lazy(), PlainTextFacade)
+    PlainTextChannel::new(
+        Channel::builder(address.into_uri()).timeout(TIMEOUT).connect_lazy(),
+        PlainTextFacade,
+    )
 }
 
 #[derive(Clone, Debug)]
@@ -66,7 +74,7 @@ pub(super) fn open_callcred_channel(
     address: Address,
     credential: Credential,
 ) -> Result<(CallCredChannel, Arc<CallCredentials>)> {
-    let mut builder = Channel::builder(address.into_uri());
+    let mut builder = Channel::builder(address.into_uri()).timeout(TIMEOUT);
     if credential.is_tls_enabled() {
         builder = builder.tls_config(credential.tls_config().clone().unwrap())?;
     }

From 760870ffacf29abf29bffd742be6ca584a1f8226 Mon Sep 17 00:00:00 2001
From: Dmitrii Ubskii <18616863+dmitrii-ubskii@users.noreply.github.com>
Date: Fri, 8 Nov 2024 15:28:30 +0000
Subject: [PATCH 2/3] docs

---
 docs/modules/ROOT/partials/rust/errors/ConnectionError.adoc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docs/modules/ROOT/partials/rust/errors/ConnectionError.adoc b/docs/modules/ROOT/partials/rust/errors/ConnectionError.adoc
index 6e11711945..da2d1ddf08 100644
--- a/docs/modules/ROOT/partials/rust/errors/ConnectionError.adoc
+++ b/docs/modules/ROOT/partials/rust/errors/ConnectionError.adoc
@@ -17,6 +17,7 @@ a| `CloudSSLCertificateNotValidated`
 a| `CloudTokenCredentialInvalid`
 a| `ConnectionFailed`
 a| `ConnectionIsClosed`
+a| `ConnectionTimedOut`
 a| `DatabaseDoesNotExist`
 a| `InvalidResponseField`
 a| `MissingPort`

From 117cff4a6e254c62b101c3c3847f5703853adf92 Mon Sep 17 00:00:00 2001
From: Dmitrii Ubskii <18616863+dmitrii-ubskii@users.noreply.github.com>
Date: Fri, 8 Nov 2024 15:59:02 +0000
Subject: [PATCH 3/3] fmt

---
 rust/src/connection/network/channel.rs | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/rust/src/connection/network/channel.rs b/rust/src/connection/network/channel.rs
index ec526d64d3..88ea721eb1 100644
--- a/rust/src/connection/network/channel.rs
+++ b/rust/src/connection/network/channel.rs
@@ -55,10 +55,7 @@ impl GRPCChannel for CallCredChannel {}
 const TIMEOUT: Duration = Duration::from_secs(60);
 
 pub(super) fn open_plaintext_channel(address: Address) -> PlainTextChannel {
-    PlainTextChannel::new(
-        Channel::builder(address.into_uri()).timeout(TIMEOUT).connect_lazy(),
-        PlainTextFacade,
-    )
+    PlainTextChannel::new(Channel::builder(address.into_uri()).timeout(TIMEOUT).connect_lazy(), PlainTextFacade)
 }
 
 #[derive(Clone, Debug)]