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