frontend/
frontend.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 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    /// The internal gRPC options for the frontend service.
52    /// it provide the same service as the public gRPC service, just only for internal use.
53    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    /// The event recorder options.
72    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
112/// The [`Frontend`] struct is the main entry point for the frontend service
113/// which contains server handlers, frontend instance and some background tasks.
114pub 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}