couchbase_core/options/
agent.rs

1/*
2 *
3 *  * Copyright (c) 2025 Couchbase, Inc.
4 *  *
5 *  * Licensed under the Apache License, Version 2.0 (the "License");
6 *  * you may not use this file except in compliance with the License.
7 *  * You may obtain a copy of the License at
8 *  *
9 *  *    http://www.apache.org/licenses/LICENSE-2.0
10 *  *
11 *  * Unless required by applicable law or agreed to in writing, software
12 *  * distributed under the License is distributed on an "AS IS" BASIS,
13 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  * See the License for the specific language governing permissions and
15 *  * limitations under the License.
16 *
17 */
18
19use crate::address::Address;
20use crate::auth_mechanism::AuthMechanism;
21use crate::authenticator::Authenticator;
22use crate::memdx::dispatcher::OrphanResponseHandler;
23use crate::tls_config::TlsConfig;
24use std::fmt::Debug;
25use std::sync::Arc;
26use std::time::Duration;
27
28#[derive(Clone)]
29#[non_exhaustive]
30pub struct AgentOptions {
31    pub seed_config: SeedConfig,
32    pub authenticator: Authenticator,
33
34    pub auth_mechanisms: Vec<AuthMechanism>,
35    pub tls_config: Option<TlsConfig>,
36    pub bucket_name: Option<String>,
37
38    pub compression_config: CompressionConfig,
39    pub config_poller_config: ConfigPollerConfig,
40    pub kv_config: KvConfig,
41    pub http_config: HttpConfig,
42    pub tcp_keep_alive_time: Option<Duration>,
43    pub orphan_response_handler: Option<OrphanResponseHandler>,
44}
45
46impl Debug for AgentOptions {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        f.debug_struct("AgentOptions")
49            .field("seed_config", &self.seed_config)
50            .field("auth_mechanisms", &self.auth_mechanisms)
51            .field("tls_config", &self.tls_config)
52            .field("bucket_name", &self.bucket_name)
53            .field("compression_config", &self.compression_config)
54            .field("config_poller_config", &self.config_poller_config)
55            .field("kv_config", &self.kv_config)
56            .field("http_config", &self.http_config)
57            .field("tcp_keep_alive_time", &self.tcp_keep_alive_time)
58            .finish()
59    }
60}
61
62impl AgentOptions {
63    pub fn new(seed_config: SeedConfig, authenticator: Authenticator) -> Self {
64        Self {
65            tls_config: None,
66            authenticator,
67            bucket_name: None,
68            seed_config,
69            compression_config: CompressionConfig::default(),
70            config_poller_config: ConfigPollerConfig::default(),
71            auth_mechanisms: vec![],
72            kv_config: KvConfig::default(),
73            http_config: HttpConfig::default(),
74            tcp_keep_alive_time: None,
75            orphan_response_handler: None,
76        }
77    }
78
79    pub fn seed_config(mut self, seed_config: SeedConfig) -> Self {
80        self.seed_config = seed_config;
81        self
82    }
83
84    pub fn authenticator(mut self, authenticator: Authenticator) -> Self {
85        self.authenticator = authenticator;
86        self
87    }
88
89    pub fn tls_config(mut self, tls_config: impl Into<Option<TlsConfig>>) -> Self {
90        self.tls_config = tls_config.into();
91        self
92    }
93
94    pub fn bucket_name(mut self, bucket_name: impl Into<Option<String>>) -> Self {
95        self.bucket_name = bucket_name.into();
96        self
97    }
98
99    pub fn compression_config(mut self, compression_config: CompressionConfig) -> Self {
100        self.compression_config = compression_config;
101        self
102    }
103
104    pub fn config_poller_config(mut self, config_poller_config: ConfigPollerConfig) -> Self {
105        self.config_poller_config = config_poller_config;
106        self
107    }
108
109    pub fn auth_mechanisms(mut self, auth_mechanisms: Vec<AuthMechanism>) -> Self {
110        self.auth_mechanisms = auth_mechanisms;
111        self
112    }
113
114    pub fn kv_config(mut self, kv_config: KvConfig) -> Self {
115        self.kv_config = kv_config;
116        self
117    }
118
119    pub fn http_config(mut self, http_config: HttpConfig) -> Self {
120        self.http_config = http_config;
121        self
122    }
123
124    pub fn tcp_keep_alive_time(mut self, tcp_keep_alive: Duration) -> Self {
125        self.tcp_keep_alive_time = Some(tcp_keep_alive);
126        self
127    }
128
129    pub fn orphan_reporter_handler(
130        mut self,
131        orphan_response_handler: OrphanResponseHandler,
132    ) -> Self {
133        self.orphan_response_handler = Some(orphan_response_handler);
134        self
135    }
136}
137
138#[derive(Default, Clone, Debug, PartialEq)]
139#[non_exhaustive]
140pub struct SeedConfig {
141    pub http_addrs: Vec<Address>,
142    pub memd_addrs: Vec<Address>,
143}
144
145impl SeedConfig {
146    pub fn new() -> Self {
147        Default::default()
148    }
149
150    pub fn http_addrs(mut self, http_addrs: Vec<Address>) -> Self {
151        self.http_addrs = http_addrs;
152        self
153    }
154
155    pub fn memd_addrs(mut self, memd_addrs: Vec<Address>) -> Self {
156        self.memd_addrs = memd_addrs;
157        self
158    }
159}
160
161#[derive(Default, Clone, Debug, PartialEq)]
162#[non_exhaustive]
163pub struct CompressionConfig {
164    pub disable_decompression: bool,
165    pub mode: CompressionMode,
166}
167
168impl CompressionConfig {
169    pub fn new(mode: CompressionMode) -> Self {
170        Self {
171            disable_decompression: false,
172            mode,
173        }
174    }
175
176    pub fn disable_decompression(mut self, disable_decompression: bool) -> Self {
177        self.disable_decompression = disable_decompression;
178        self
179    }
180
181    pub fn mode(mut self, mode: CompressionMode) -> Self {
182        self.mode = mode;
183        self
184    }
185}
186
187#[derive(Clone, Debug, PartialEq)]
188#[non_exhaustive]
189pub enum CompressionMode {
190    Enabled { min_size: usize, min_ratio: f64 },
191    Disabled,
192}
193
194impl Default for CompressionMode {
195    fn default() -> Self {
196        Self::Enabled {
197            min_size: 32,
198            min_ratio: 0.83,
199        }
200    }
201}
202
203#[derive(Clone, Debug, PartialEq)]
204#[non_exhaustive]
205pub struct ConfigPollerConfig {
206    pub poll_interval: Duration,
207}
208
209impl ConfigPollerConfig {
210    pub fn new() -> Self {
211        Default::default()
212    }
213
214    pub fn poll_interval(mut self, poll_interval: Duration) -> Self {
215        self.poll_interval = poll_interval;
216        self
217    }
218}
219
220impl Default for ConfigPollerConfig {
221    fn default() -> Self {
222        Self {
223            poll_interval: Duration::from_millis(2500),
224        }
225    }
226}
227
228#[derive(Clone, Debug, PartialEq)]
229#[non_exhaustive]
230pub struct KvConfig {
231    pub enable_mutation_tokens: bool,
232    pub enable_server_durations: bool,
233    pub num_connections: usize,
234    pub connect_timeout: Duration,
235    pub connect_throttle_timeout: Duration,
236}
237
238impl KvConfig {
239    pub fn new() -> Self {
240        Self::default()
241    }
242
243    pub fn enable_mutation_tokens(mut self, enable: bool) -> Self {
244        self.enable_mutation_tokens = enable;
245        self
246    }
247
248    pub fn enable_server_durations(mut self, enable: bool) -> Self {
249        self.enable_server_durations = enable;
250        self
251    }
252
253    pub fn connect_timeout(mut self, connect_timeout: Duration) -> Self {
254        self.connect_timeout = connect_timeout;
255        self
256    }
257
258    pub fn connect_throttle_timeout(mut self, connect_throttle_timeout: Duration) -> Self {
259        self.connect_throttle_timeout = connect_throttle_timeout;
260        self
261    }
262
263    pub fn num_connections(mut self, num: usize) -> Self {
264        self.num_connections = num;
265        self
266    }
267}
268
269impl Default for KvConfig {
270    fn default() -> Self {
271        Self {
272            enable_mutation_tokens: true,
273            enable_server_durations: true,
274            num_connections: 1,
275            connect_timeout: Duration::from_secs(10),
276            connect_throttle_timeout: Duration::from_secs(5),
277        }
278    }
279}
280
281#[derive(Clone, Debug, PartialEq)]
282#[non_exhaustive]
283pub struct HttpConfig {
284    pub max_idle_connections_per_host: Option<usize>,
285    pub idle_connection_timeout: Duration,
286}
287
288impl HttpConfig {
289    pub fn new() -> Self {
290        Self::default()
291    }
292
293    pub fn max_idle_connections_per_host(mut self, max_idle_connections_per_host: usize) -> Self {
294        self.max_idle_connections_per_host = Some(max_idle_connections_per_host);
295        self
296    }
297
298    pub fn idle_connection_timeout(mut self, idle_connection_timeout: Duration) -> Self {
299        self.idle_connection_timeout = idle_connection_timeout;
300        self
301    }
302}
303
304impl Default for HttpConfig {
305    fn default() -> Self {
306        Self {
307            max_idle_connections_per_host: None,
308            idle_connection_timeout: Duration::from_secs(1),
309        }
310    }
311}