Skip to main content

linera_rpc/grpc/
transport.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::NodeOptions;
5
6/// Configuration for creating gRPC transport channels.
7#[derive(Clone, Debug, Default)]
8pub struct Options {
9    /// The maximum time to wait when establishing a connection.
10    pub connect_timeout: Option<linera_base::time::Duration>,
11    /// The maximum time to wait for a request to complete.
12    pub timeout: Option<linera_base::time::Duration>,
13}
14
15impl From<&'_ NodeOptions> for Options {
16    fn from(node_options: &NodeOptions) -> Self {
17        Self {
18            connect_timeout: Some(node_options.send_timeout),
19            timeout: Some(node_options.recv_timeout),
20        }
21    }
22}
23
24cfg_if::cfg_if! {
25    if #[cfg(web)] {
26        pub use tonic_web_wasm_client::{Client as Channel, Error};
27
28        /// Creates a transport channel for the given address.
29        pub fn create_channel(address: String, _options: &Options) -> Result<Channel, Error> {
30            // TODO(#1817): this should respect `options`
31            Ok(tonic_web_wasm_client::Client::new(address))
32        }
33    } else {
34        pub use tonic::transport::{Channel, Error};
35
36        /// Creates a transport channel for the given address.
37        pub fn create_channel(
38            address: String,
39            options: &Options,
40        ) -> Result<Channel, Error> {
41            let mut endpoint = tonic::transport::Endpoint::from_shared(address)?
42                .tls_config(tonic::transport::channel::ClientTlsConfig::default().with_webpki_roots())?
43                .tcp_keepalive(Some(std::time::Duration::from_secs(60)))
44                .http2_keep_alive_interval(std::time::Duration::from_secs(30))
45                .keep_alive_timeout(std::time::Duration::from_secs(10))
46                .keep_alive_while_idle(true);
47
48            if let Some(timeout) = options.connect_timeout {
49                endpoint = endpoint.connect_timeout(timeout);
50            }
51            if let Some(timeout) = options.timeout {
52                endpoint = endpoint.timeout(timeout);
53            }
54            Ok(endpoint.connect_lazy())
55        }
56    }
57}