Skip to main content

miden_node_utils/
clap.rs

1//! Public module for share clap pieces to reduce duplication
2
3use std::num::{NonZeroU32, NonZeroU64};
4use std::time::Duration;
5
6const DEFAULT_REQUEST_TIMEOUT: Duration = Duration::from_secs(10);
7const TEST_REQUEST_TIMEOUT: Duration = Duration::from_secs(5);
8const DEFAULT_MAX_CONNECTION_AGE: Duration = Duration::from_secs(30 * 60);
9const DEFAULT_REPLENISH_N_PER_SECOND_PER_IP: NonZeroU64 = NonZeroU64::new(16).unwrap();
10const DEFAULT_BURST_SIZE: NonZeroU32 = NonZeroU32::new(128).unwrap();
11const DEFAULT_MAX_CONCURRENT_CONNECTIONS: u64 = 1_000;
12const BENCH_REQUEST_TIMEOUT: Duration = Duration::from_secs(24 * 60 * 60);
13
14// Formats a Duration into a human-readable string for display in clap help text
15// and yields a &'static str by _leaking_ the string deliberately.
16pub fn duration_to_human_readable_string(duration: Duration) -> &'static str {
17    Box::new(humantime::format_duration(duration).to_string()).leak()
18}
19
20#[derive(clap::Args, Copy, Clone, Debug, PartialEq, Eq)]
21pub struct GrpcOptionsInternal {
22    /// Maximum duration a gRPC request is allocated before being dropped by the server.
23    ///
24    /// This may occur if the server is overloaded or due to an internal bug.
25    #[arg(
26        long = "grpc.timeout",
27        default_value = duration_to_human_readable_string(DEFAULT_REQUEST_TIMEOUT),
28        value_parser = humantime::parse_duration,
29        value_name = "DURATION"
30    )]
31    pub request_timeout: Duration,
32}
33
34impl Default for GrpcOptionsInternal {
35    fn default() -> Self {
36        Self { request_timeout: DEFAULT_REQUEST_TIMEOUT }
37    }
38}
39
40impl From<GrpcOptionsExternal> for GrpcOptionsInternal {
41    fn from(value: GrpcOptionsExternal) -> Self {
42        let GrpcOptionsExternal { request_timeout, .. } = value;
43        Self { request_timeout }
44    }
45}
46
47impl GrpcOptionsInternal {
48    pub fn test() -> Self {
49        GrpcOptionsExternal::test().into()
50    }
51    pub fn bench() -> Self {
52        GrpcOptionsExternal::bench().into()
53    }
54}
55
56#[derive(clap::Args, Copy, Clone, Debug, PartialEq, Eq)]
57pub struct GrpcOptionsExternal {
58    /// Maximum duration a gRPC request is allocated before being dropped by the server.
59    ///
60    /// This may occur if the server is overloaded or due to an internal bug.
61    #[arg(
62        long = "grpc.timeout",
63        default_value = duration_to_human_readable_string(DEFAULT_REQUEST_TIMEOUT),
64        value_parser = humantime::parse_duration,
65        value_name = "DURATION"
66    )]
67    pub request_timeout: Duration,
68
69    /// Maximum duration of a connection before we drop it on the server side irrespective of
70    /// activity.
71    #[arg(
72        long = "grpc.max_connection_age",
73        default_value = duration_to_human_readable_string(DEFAULT_MAX_CONNECTION_AGE),
74        value_parser = humantime::parse_duration,
75        value_name = "MAX_CONNECTION_AGE"
76    )]
77    pub max_connection_age: Duration,
78
79    /// Number of connections to be served before the "API tokens" need to be replenished
80    /// per IP address.
81    #[arg(
82        long = "grpc.burst_size",
83        default_value_t = DEFAULT_BURST_SIZE,
84        value_name = "BURST_SIZE"
85    )]
86    pub burst_size: NonZeroU32,
87
88    /// Number of request credits replenished per second per IP.
89    #[arg(
90        long = "grpc.replenish_n_per_second",
91        default_value_t = DEFAULT_REPLENISH_N_PER_SECOND_PER_IP,
92        value_name = "DEFAULT_REPLENISH_N_PER_SECOND"
93    )]
94    pub replenish_n_per_second_per_ip: NonZeroU64,
95
96    /// Maximum number of concurrent connections accepted by the server.
97    #[arg(
98        long = "grpc.max_concurrent_connections",
99        default_value_t = DEFAULT_MAX_CONCURRENT_CONNECTIONS,
100        value_name = "MAX_CONCURRENT_CONNECTIONS"
101    )]
102    pub max_concurrent_connections: u64,
103}
104
105impl Default for GrpcOptionsExternal {
106    fn default() -> Self {
107        Self {
108            request_timeout: DEFAULT_REQUEST_TIMEOUT,
109            max_connection_age: DEFAULT_MAX_CONNECTION_AGE,
110            burst_size: DEFAULT_BURST_SIZE,
111            replenish_n_per_second_per_ip: DEFAULT_REPLENISH_N_PER_SECOND_PER_IP,
112            max_concurrent_connections: DEFAULT_MAX_CONCURRENT_CONNECTIONS,
113        }
114    }
115}
116
117impl GrpcOptionsExternal {
118    pub fn test() -> Self {
119        Self {
120            request_timeout: TEST_REQUEST_TIMEOUT,
121            ..Default::default()
122        }
123    }
124
125    /// Return a gRPC config for benchmarking.
126    pub fn bench() -> Self {
127        Self {
128            request_timeout: BENCH_REQUEST_TIMEOUT,
129            max_connection_age: BENCH_REQUEST_TIMEOUT,
130            burst_size: NonZeroU32::new(100_000).unwrap(),
131            replenish_n_per_second_per_ip: NonZeroU64::new(100_000).unwrap(),
132            max_concurrent_connections: u64::MAX,
133        }
134    }
135}