1use common_base::readable_size::ReadableSize;
16use common_config::{Configurable, KvBackendConfig};
17use common_event_recorder::EventRecorderOptions;
18use common_memory_manager::OnExhaustedPolicy;
19use common_options::memory::MemoryOptions;
20use common_telemetry::logging::{LoggingOptions, SlowQueryOptions, TracingOptions};
21use common_wal::config::DatanodeWalConfig;
22use datanode::config::{DatanodeOptions, ProcedureConfig, RegionEngineConfig, StorageConfig};
23use file_engine::config::EngineConfig as FileEngineConfig;
24use flow::FlowConfig;
25use frontend::frontend::FrontendOptions;
26use frontend::service_config::{
27 InfluxdbOptions, JaegerOptions, MysqlOptions, OpentsdbOptions, OtlpOptions, PostgresOptions,
28 PromStoreOptions,
29};
30use mito2::config::MitoConfig;
31use pipeline::PipelineOptions;
32use query::options::QueryOptions;
33use serde::{Deserialize, Serialize};
34use servers::grpc::GrpcOptions;
35use servers::http::HttpOptions;
36
37#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
38#[serde(default)]
39pub struct StandaloneOptions {
40 pub enable_telemetry: bool,
41 pub default_timezone: Option<String>,
42 pub default_column_prefix: Option<String>,
43 pub auto_create_table: bool,
47 pub max_in_flight_write_bytes: ReadableSize,
50 pub write_bytes_exhausted_policy: OnExhaustedPolicy,
53 pub http: HttpOptions,
54 pub grpc: GrpcOptions,
55 pub mysql: MysqlOptions,
56 pub postgres: PostgresOptions,
57 pub opentsdb: OpentsdbOptions,
58 pub influxdb: InfluxdbOptions,
59 pub jaeger: JaegerOptions,
60 pub otlp: OtlpOptions,
61 pub prom_store: PromStoreOptions,
62 pub wal: DatanodeWalConfig,
63 pub storage: StorageConfig,
64 pub metadata_store: KvBackendConfig,
65 pub procedure: ProcedureConfig,
66 pub flow: FlowConfig,
67 pub logging: LoggingOptions,
68 pub user_provider: Option<String>,
69 pub region_engine: Vec<RegionEngineConfig>,
71 pub tracing: TracingOptions,
72 pub init_regions_in_background: bool,
73 pub init_regions_parallelism: usize,
74 pub slow_query: SlowQueryOptions,
75 pub query: QueryOptions,
76 pub memory: MemoryOptions,
77 pub pipeline: PipelineOptions,
79 pub event_recorder: EventRecorderOptions,
81 pub heartbeat_env_vars: Vec<String>,
83}
84
85impl Default for StandaloneOptions {
86 fn default() -> Self {
87 Self {
88 enable_telemetry: true,
89 default_timezone: None,
90 default_column_prefix: None,
91 auto_create_table: true,
92 max_in_flight_write_bytes: ReadableSize(0),
93 write_bytes_exhausted_policy: OnExhaustedPolicy::default(),
94 http: HttpOptions::default(),
95 grpc: GrpcOptions::default(),
96 mysql: MysqlOptions::default(),
97 postgres: PostgresOptions::default(),
98 opentsdb: OpentsdbOptions::default(),
99 influxdb: InfluxdbOptions::default(),
100 jaeger: JaegerOptions::default(),
101 otlp: OtlpOptions::default(),
102 prom_store: PromStoreOptions::default(),
103 wal: DatanodeWalConfig::default(),
104 storage: StorageConfig::default(),
105 metadata_store: KvBackendConfig::default(),
106 procedure: ProcedureConfig::default(),
107 flow: FlowConfig::default(),
108 logging: LoggingOptions::default(),
109 user_provider: None,
110 region_engine: vec![
111 RegionEngineConfig::Mito(MitoConfig::default()),
112 RegionEngineConfig::File(FileEngineConfig::default()),
113 ],
114 tracing: TracingOptions::default(),
115 init_regions_in_background: false,
116 init_regions_parallelism: 16,
117 slow_query: SlowQueryOptions::default(),
118 query: QueryOptions::default(),
119 memory: MemoryOptions::default(),
120 pipeline: PipelineOptions::default(),
121 event_recorder: EventRecorderOptions::default(),
122 heartbeat_env_vars: vec![],
123 }
124 }
125}
126
127impl Configurable for StandaloneOptions {
128 fn env_list_keys() -> Option<&'static [&'static str]> {
129 Some(&[
130 "heartbeat_env_vars",
131 "wal.broker_endpoints",
132 "event_recorder.event_types",
133 ])
134 }
135}
136
137#[allow(clippy::from_over_into)]
141impl Into<FrontendOptions> for StandaloneOptions {
142 fn into(self) -> FrontendOptions {
143 self.frontend_options()
144 }
145}
146
147impl StandaloneOptions {
148 pub fn frontend_options(&self) -> FrontendOptions {
149 let cloned_opts = self.clone();
150 FrontendOptions {
151 default_timezone: cloned_opts.default_timezone,
152 auto_create_table: cloned_opts.auto_create_table,
153 max_in_flight_write_bytes: cloned_opts.max_in_flight_write_bytes,
154 write_bytes_exhausted_policy: cloned_opts.write_bytes_exhausted_policy,
155 http: cloned_opts.http,
156 grpc: cloned_opts.grpc,
157 mysql: cloned_opts.mysql,
158 postgres: cloned_opts.postgres,
159 opentsdb: cloned_opts.opentsdb,
160 influxdb: cloned_opts.influxdb,
161 jaeger: cloned_opts.jaeger,
162 otlp: cloned_opts.otlp,
163 prom_store: cloned_opts.prom_store,
164 meta_client: None,
165 logging: cloned_opts.logging,
166 user_provider: cloned_opts.user_provider,
167 query: cloned_opts.query,
168 slow_query: cloned_opts.slow_query,
169 pipeline: cloned_opts.pipeline,
170 event_recorder: cloned_opts.event_recorder,
171 heartbeat_env_vars: cloned_opts.heartbeat_env_vars.clone(),
172 ..Default::default()
173 }
174 }
175
176 pub fn datanode_options(&self) -> DatanodeOptions {
177 let cloned_opts = self.clone();
178 DatanodeOptions {
179 node_id: Some(0),
180 enable_telemetry: cloned_opts.enable_telemetry,
181 wal: cloned_opts.wal,
182 storage: cloned_opts.storage,
183 region_engine: cloned_opts.region_engine,
184 grpc: cloned_opts.grpc,
185 init_regions_in_background: cloned_opts.init_regions_in_background,
186 init_regions_parallelism: cloned_opts.init_regions_parallelism,
187 query: cloned_opts.query,
188 heartbeat_env_vars: cloned_opts.heartbeat_env_vars,
189 ..Default::default()
190 }
191 }
192
193 pub fn sanitize(&mut self) {
195 if self.storage.is_object_storage() {
196 self.storage
197 .store
198 .cache_config_mut()
199 .unwrap()
200 .sanitize(&self.storage.data_home);
201 }
202 }
203}
204
205#[cfg(test)]
206mod tests {
207 use std::sync::Arc;
208
209 use common_event_recorder::EventTypeFilter;
210
211 use super::*;
212
213 #[test]
214 fn test_event_recorder_event_types_preserve_filter_semantics() {
215 let all: StandaloneOptions = toml::from_str("").unwrap();
216 let none: StandaloneOptions = toml::from_str("[event_recorder]\nevent_types = []").unwrap();
217 let selected: StandaloneOptions =
218 toml::from_str("[event_recorder]\nevent_types = ['create_database']").unwrap();
219
220 assert!(all.event_recorder.event_types.allows("future_event"));
221 assert_eq!(
222 none.event_recorder.event_types.as_ref(),
223 &EventTypeFilter::Only(Default::default())
224 );
225 assert!(
226 selected
227 .event_recorder
228 .event_types
229 .allows("create_database")
230 );
231 assert!(!selected.event_recorder.event_types.allows("drop_database"));
232
233 let frontend_options = selected.frontend_options();
234 assert!(Arc::ptr_eq(
235 &selected.event_recorder.event_types,
236 &frontend_options.event_recorder.event_types,
237 ));
238 }
239
240 #[test]
241 fn test_query_options_propagated_to_components() {
242 let mut options = StandaloneOptions::default();
243 options.query.parallelism = 4;
244
245 assert_eq!(options.frontend_options().query.parallelism, 4);
246 assert_eq!(options.datanode_options().query.parallelism, 4);
247 }
248}