Skip to main content

linera_rpc/
node_provider.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use linera_base::time::Duration;
5use linera_core::node::{NodeError, ValidatorNodeProvider};
6
7#[cfg(with_simple_network)]
8use crate::simple::SimpleNodeProvider;
9use crate::{client::Client, grpc::GrpcNodeProvider};
10
11/// A general node provider which delegates node provision to the underlying
12/// node provider according to the `ValidatorPublicNetworkConfig`.
13#[derive(Clone)]
14pub struct NodeProvider {
15    grpc: GrpcNodeProvider,
16    #[cfg(with_simple_network)]
17    simple: SimpleNodeProvider,
18}
19
20impl NodeProvider {
21    pub fn new(options: NodeOptions) -> Self {
22        Self {
23            grpc: GrpcNodeProvider::new(options),
24            #[cfg(with_simple_network)]
25            simple: SimpleNodeProvider::new(options),
26        }
27    }
28}
29
30impl ValidatorNodeProvider for NodeProvider {
31    type Node = Client;
32
33    fn make_node(&self, address: &str) -> anyhow::Result<Self::Node, NodeError> {
34        let address = address.to_lowercase();
35
36        #[cfg(with_simple_network)]
37        if address.starts_with("tcp") || address.starts_with("udp") {
38            return Ok(Client::Simple(self.simple.make_node(&address)?));
39        }
40
41        if address.starts_with("grpc") {
42            return Ok(Client::Grpc(self.grpc.make_node(&address)?));
43        }
44
45        Err(NodeError::CannotResolveValidatorAddress { address })
46    }
47}
48
49/// Default maximum backoff delay (30 seconds), following Google Cloud's recommendation.
50/// References:
51/// - <https://cloud.google.com/storage/docs/retry-strategy>
52/// - <https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html>
53/// - <https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md>
54pub const DEFAULT_MAX_BACKOFF: Duration = Duration::from_secs(30);
55
56#[derive(Copy, Clone)]
57pub struct NodeOptions {
58    pub send_timeout: Duration,
59    pub recv_timeout: Duration,
60    pub retry_delay: Duration,
61    pub max_retries: u32,
62    pub max_backoff: Duration,
63}
64
65impl Default for NodeOptions {
66    fn default() -> Self {
67        Self {
68            send_timeout: Duration::ZERO,
69            recv_timeout: Duration::ZERO,
70            retry_delay: Duration::ZERO,
71            max_retries: 0,
72            max_backoff: DEFAULT_MAX_BACKOFF,
73        }
74    }
75}