Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/Vine/Client/
ConnectToSideCar.rs

1#![allow(non_snake_case)]
2
3//! Establish a gRPC connection to a Cocoon sidecar with exponential
4//! back-off retry. On success initialises the per-connection metadata
5//! tracked by `Shared::CONNECTION_METADATA`.
6
7use std::time::{Duration, Instant};
8
9use crate::{
10	Vine::{
11		Client::{
12			Shared::{
13				CONNECTION_METADATA,
14				ConnectionMetadata,
15				FireConnectionNotify,
16				MAX_RETRY_ATTEMPTS,
17				RETRY_BASE_DELAY_MS,
18			},
19			TryConnectSingle,
20		},
21		Error::VineError,
22	},
23	dev_log,
24};
25
26pub async fn Fn(SideCarIdentifier:String, Address:String) -> Result<(), VineError> {
27	dev_log!(
28		"grpc",
29		"[VineClient] Connecting to sidecar '{}' at '{}'...",
30		SideCarIdentifier,
31		Address
32	);
33
34	let Endpoint = format!("http://{}", Address);
35
36	if Endpoint.len() > 256 {
37		return Err(VineError::RPCError(
38			"Invalid endpoint address: exceeds maximum length".to_string(),
39		));
40	}
41
42	let mut LastError = None;
43
44	for Attempt in 1..=MAX_RETRY_ATTEMPTS {
45		let Result = TryConnectSingle::Fn(&SideCarIdentifier, &Endpoint).await;
46
47		if Result.is_ok() {
48			CONNECTION_METADATA.lock().insert(
49				SideCarIdentifier.clone(),
50				ConnectionMetadata { LastActivity:Instant::now(), FailureCount:0, IsHealthy:true },
51			);
52
53			dev_log!("grpc", "[VineClient] Successfully connected to sidecar '{}'", SideCarIdentifier);
54
55			// Unblock any `WaitForClientConnection` callers immediately.
56			FireConnectionNotify(&SideCarIdentifier);
57
58			return Result;
59		}
60
61		LastError = Some(Result.unwrap_err());
62
63		if Attempt < MAX_RETRY_ATTEMPTS {
64			let DelayMilliseconds = RETRY_BASE_DELAY_MS * 2_u64.pow(Attempt as u32);
65
66			tokio::time::sleep(Duration::from_millis(DelayMilliseconds)).await;
67		}
68	}
69
70	Err(LastError.unwrap_or_else(|| VineError::RPCError("Connection failed".to_string())))
71}