Skip to main content

standalone/
options.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use common_base::readable_size::ReadableSize;
16use common_config::{Configurable, KvBackendConfig};
17use common_memory_manager::OnExhaustedPolicy;
18use common_options::memory::MemoryOptions;
19use common_telemetry::logging::{LoggingOptions, SlowQueryOptions, TracingOptions};
20use common_wal::config::DatanodeWalConfig;
21use datanode::config::{DatanodeOptions, ProcedureConfig, RegionEngineConfig, StorageConfig};
22use file_engine::config::EngineConfig as FileEngineConfig;
23use flow::FlowConfig;
24use frontend::frontend::FrontendOptions;
25use frontend::service_config::{
26    InfluxdbOptions, JaegerOptions, MysqlOptions, OpentsdbOptions, PostgresOptions,
27    PromStoreOptions,
28};
29use mito2::config::MitoConfig;
30use query::options::QueryOptions;
31use serde::{Deserialize, Serialize};
32use servers::grpc::GrpcOptions;
33use servers::http::HttpOptions;
34
35#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
36#[serde(default)]
37pub struct StandaloneOptions {
38    pub enable_telemetry: bool,
39    pub default_timezone: Option<String>,
40    pub default_column_prefix: Option<String>,
41    /// Server-side global switch for auto table creation on write.
42    /// Upper bound: when `false`, missing tables are never auto-created even if a
43    /// request sets the `auto_create_table` hint to `true`. Default: `true`.
44    pub auto_create_table: bool,
45    /// Maximum total memory for all concurrent write request bodies and messages (HTTP, gRPC, Flight).
46    /// Set to 0 to disable the limit. Default: "0" (unlimited)
47    pub max_in_flight_write_bytes: ReadableSize,
48    /// Policy when write bytes quota is exhausted.
49    /// Options: "wait" (default, 10s), "wait(<duration>)", "fail"
50    pub write_bytes_exhausted_policy: OnExhaustedPolicy,
51    pub http: HttpOptions,
52    pub grpc: GrpcOptions,
53    pub mysql: MysqlOptions,
54    pub postgres: PostgresOptions,
55    pub opentsdb: OpentsdbOptions,
56    pub influxdb: InfluxdbOptions,
57    pub jaeger: JaegerOptions,
58    pub prom_store: PromStoreOptions,
59    pub wal: DatanodeWalConfig,
60    pub storage: StorageConfig,
61    pub metadata_store: KvBackendConfig,
62    pub procedure: ProcedureConfig,
63    pub flow: FlowConfig,
64    pub logging: LoggingOptions,
65    pub user_provider: Option<String>,
66    /// Options for different store engines.
67    pub region_engine: Vec<RegionEngineConfig>,
68    pub tracing: TracingOptions,
69    pub init_regions_in_background: bool,
70    pub init_regions_parallelism: usize,
71    pub slow_query: SlowQueryOptions,
72    pub query: QueryOptions,
73    pub memory: MemoryOptions,
74    /// Environment variable keys to read and report in heartbeat messages.
75    pub heartbeat_env_vars: Vec<String>,
76}
77
78impl Default for StandaloneOptions {
79    fn default() -> Self {
80        Self {
81            enable_telemetry: true,
82            default_timezone: None,
83            default_column_prefix: None,
84            auto_create_table: true,
85            max_in_flight_write_bytes: ReadableSize(0),
86            write_bytes_exhausted_policy: OnExhaustedPolicy::default(),
87            http: HttpOptions::default(),
88            grpc: GrpcOptions::default(),
89            mysql: MysqlOptions::default(),
90            postgres: PostgresOptions::default(),
91            opentsdb: OpentsdbOptions::default(),
92            influxdb: InfluxdbOptions::default(),
93            jaeger: JaegerOptions::default(),
94            prom_store: PromStoreOptions::default(),
95            wal: DatanodeWalConfig::default(),
96            storage: StorageConfig::default(),
97            metadata_store: KvBackendConfig::default(),
98            procedure: ProcedureConfig::default(),
99            flow: FlowConfig::default(),
100            logging: LoggingOptions::default(),
101            user_provider: None,
102            region_engine: vec![
103                RegionEngineConfig::Mito(MitoConfig::default()),
104                RegionEngineConfig::File(FileEngineConfig::default()),
105            ],
106            tracing: TracingOptions::default(),
107            init_regions_in_background: false,
108            init_regions_parallelism: 16,
109            slow_query: SlowQueryOptions::default(),
110            query: QueryOptions::default(),
111            memory: MemoryOptions::default(),
112            heartbeat_env_vars: vec![],
113        }
114    }
115}
116
117impl Configurable for StandaloneOptions {
118    fn env_list_keys() -> Option<&'static [&'static str]> {
119        Some(&["heartbeat_env_vars", "wal.broker_endpoints"])
120    }
121}
122
123/// The [`StandaloneOptions`] is only defined in `standalone` crate,
124/// we don't want to make `frontend` depends on it, so impl [`Into`]
125/// rather than [`From`].
126#[allow(clippy::from_over_into)]
127impl Into<FrontendOptions> for StandaloneOptions {
128    fn into(self) -> FrontendOptions {
129        self.frontend_options()
130    }
131}
132
133impl StandaloneOptions {
134    pub fn frontend_options(&self) -> FrontendOptions {
135        let cloned_opts = self.clone();
136        FrontendOptions {
137            default_timezone: cloned_opts.default_timezone,
138            auto_create_table: cloned_opts.auto_create_table,
139            max_in_flight_write_bytes: cloned_opts.max_in_flight_write_bytes,
140            write_bytes_exhausted_policy: cloned_opts.write_bytes_exhausted_policy,
141            http: cloned_opts.http,
142            grpc: cloned_opts.grpc,
143            mysql: cloned_opts.mysql,
144            postgres: cloned_opts.postgres,
145            opentsdb: cloned_opts.opentsdb,
146            influxdb: cloned_opts.influxdb,
147            jaeger: cloned_opts.jaeger,
148            prom_store: cloned_opts.prom_store,
149            meta_client: None,
150            logging: cloned_opts.logging,
151            user_provider: cloned_opts.user_provider,
152            slow_query: cloned_opts.slow_query,
153            heartbeat_env_vars: cloned_opts.heartbeat_env_vars.clone(),
154            ..Default::default()
155        }
156    }
157
158    pub fn datanode_options(&self) -> DatanodeOptions {
159        let cloned_opts = self.clone();
160        DatanodeOptions {
161            node_id: Some(0),
162            enable_telemetry: cloned_opts.enable_telemetry,
163            wal: cloned_opts.wal,
164            storage: cloned_opts.storage,
165            region_engine: cloned_opts.region_engine,
166            grpc: cloned_opts.grpc,
167            init_regions_in_background: cloned_opts.init_regions_in_background,
168            init_regions_parallelism: cloned_opts.init_regions_parallelism,
169            query: cloned_opts.query,
170            heartbeat_env_vars: cloned_opts.heartbeat_env_vars,
171            ..Default::default()
172        }
173    }
174
175    /// Sanitize the `StandaloneOptions` to ensure the config is valid.
176    pub fn sanitize(&mut self) {
177        if self.storage.is_object_storage() {
178            self.storage
179                .store
180                .cache_config_mut()
181                .unwrap()
182                .sanitize(&self.storage.data_home);
183        }
184    }
185}