1use std::sync::Arc;
16
17use common_base::readable_size::ReadableSize;
18use common_config::config::Configurable;
19use common_event_recorder::EventRecorderOptions;
20use common_options::datanode::DatanodeClientOptions;
21use common_options::memory::MemoryOptions;
22use common_telemetry::logging::{LoggingOptions, SlowQueryOptions, TracingOptions};
23use meta_client::MetaClientOptions;
24use query::options::QueryOptions;
25use serde::{Deserialize, Serialize};
26use servers::export_metrics::{ExportMetricsOption, ExportMetricsTask};
27use servers::grpc::GrpcOptions;
28use servers::heartbeat_options::HeartbeatOptions;
29use servers::http::HttpOptions;
30use servers::server::ServerHandlers;
31use snafu::ResultExt;
32
33use crate::error;
34use crate::error::Result;
35use crate::heartbeat::HeartbeatTask;
36use crate::instance::Instance;
37use crate::instance::prom_store::ExportMetricHandler;
38use crate::service_config::{
39 InfluxdbOptions, JaegerOptions, MysqlOptions, OpentsdbOptions, OtlpOptions, PostgresOptions,
40 PromStoreOptions,
41};
42
43#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
44#[serde(default)]
45pub struct FrontendOptions {
46 pub node_id: Option<String>,
47 pub default_timezone: Option<String>,
48 pub heartbeat: HeartbeatOptions,
49 pub http: HttpOptions,
50 pub grpc: GrpcOptions,
51 pub internal_grpc: Option<GrpcOptions>,
54 pub mysql: MysqlOptions,
55 pub postgres: PostgresOptions,
56 pub opentsdb: OpentsdbOptions,
57 pub influxdb: InfluxdbOptions,
58 pub prom_store: PromStoreOptions,
59 pub jaeger: JaegerOptions,
60 pub otlp: OtlpOptions,
61 pub meta_client: Option<MetaClientOptions>,
62 pub logging: LoggingOptions,
63 pub datanode: DatanodeClientOptions,
64 pub user_provider: Option<String>,
65 pub export_metrics: ExportMetricsOption,
66 pub tracing: TracingOptions,
67 pub query: QueryOptions,
68 pub max_in_flight_write_bytes: Option<ReadableSize>,
69 pub slow_query: SlowQueryOptions,
70 pub memory: MemoryOptions,
71 pub event_recorder: EventRecorderOptions,
73}
74
75impl Default for FrontendOptions {
76 fn default() -> Self {
77 Self {
78 node_id: None,
79 default_timezone: None,
80 heartbeat: HeartbeatOptions::frontend_default(),
81 http: HttpOptions::default(),
82 grpc: GrpcOptions::default(),
83 internal_grpc: None,
84 mysql: MysqlOptions::default(),
85 postgres: PostgresOptions::default(),
86 opentsdb: OpentsdbOptions::default(),
87 influxdb: InfluxdbOptions::default(),
88 jaeger: JaegerOptions::default(),
89 prom_store: PromStoreOptions::default(),
90 otlp: OtlpOptions::default(),
91 meta_client: None,
92 logging: LoggingOptions::default(),
93 datanode: DatanodeClientOptions::default(),
94 user_provider: None,
95 export_metrics: ExportMetricsOption::default(),
96 tracing: TracingOptions::default(),
97 query: QueryOptions::default(),
98 max_in_flight_write_bytes: None,
99 slow_query: SlowQueryOptions::default(),
100 memory: MemoryOptions::default(),
101 event_recorder: EventRecorderOptions::default(),
102 }
103 }
104}
105
106impl Configurable for FrontendOptions {
107 fn env_list_keys() -> Option<&'static [&'static str]> {
108 Some(&["meta_client.metasrv_addrs"])
109 }
110}
111
112pub struct Frontend {
115 pub instance: Arc<Instance>,
116 pub servers: ServerHandlers,
117 pub heartbeat_task: Option<HeartbeatTask>,
118 pub export_metrics_task: Option<ExportMetricsTask>,
119}
120
121impl Frontend {
122 pub async fn start(&mut self) -> Result<()> {
123 if let Some(t) = &self.heartbeat_task {
124 t.start().await?;
125 }
126
127 if let Some(t) = self.export_metrics_task.as_ref() {
128 if t.send_by_handler {
129 let inserter = self.instance.inserter().clone();
130 let statement_executor = self.instance.statement_executor().clone();
131 let handler = ExportMetricHandler::new_handler(inserter, statement_executor);
132 t.start(Some(handler)).context(error::StartServerSnafu)?
133 } else {
134 t.start(None).context(error::StartServerSnafu)?;
135 }
136 }
137
138 self.servers
139 .start_all()
140 .await
141 .context(error::StartServerSnafu)
142 }
143
144 pub async fn shutdown(&mut self) -> Result<()> {
145 self.servers
146 .shutdown_all()
147 .await
148 .context(error::ShutdownServerSnafu)
149 }
150
151 pub fn server_handlers(&self) -> &ServerHandlers {
152 &self.servers
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159
160 #[test]
161 fn test_toml() {
162 let opts = FrontendOptions::default();
163 let toml_string = toml::to_string(&opts).unwrap();
164 let _parsed: FrontendOptions = toml::from_str(&toml_string).unwrap();
165 }
166}