servers/postgres/
server.rs1use std::any::Any;
16use std::future::Future;
17use std::net::SocketAddr;
18use std::sync::Arc;
19
20use ::auth::UserProviderRef;
21use async_trait::async_trait;
22use catalog::process_manager::ProcessManagerRef;
23use common_runtime::Runtime;
24use common_runtime::runtime::RuntimeTrait;
25use common_telemetry::{debug, warn};
26use futures::StreamExt;
27use pgwire::tokio::process_socket;
28use tokio_rustls::TlsAcceptor;
29
30use crate::error::Result;
31use crate::postgres::{MakePostgresServerHandler, MakePostgresServerHandlerBuilder};
32use crate::query_handler::CopyInHandlerRef;
33use crate::query_handler::InfluxdbLineProtocolHandlerRef;
34use crate::query_handler::sql::ServerSqlQueryHandlerRef;
35use crate::server::{AbortableStream, BaseTcpServer, Server};
36use crate::tls::ReloadableTlsServerConfig;
37
38pub struct PostgresServer {
39 base_server: BaseTcpServer,
40 make_handler: Arc<MakePostgresServerHandler>,
41 tls_server_config: Arc<ReloadableTlsServerConfig>,
42 keep_alive_secs: u64,
43 batching_enabled: bool,
44 influxdb_handler: Option<InfluxdbLineProtocolHandlerRef>,
45 bind_addr: Option<SocketAddr>,
46 process_manager: Option<ProcessManagerRef>,
47}
48
49impl PostgresServer {
50 #[allow(clippy::too_many_arguments)]
57 pub fn new(
58 query_handler: ServerSqlQueryHandlerRef,
59 copy_in_handler: CopyInHandlerRef,
60 force_tls: bool,
61 tls_server_config: Arc<ReloadableTlsServerConfig>,
62 keep_alive_secs: u64,
63 io_runtime: Runtime,
64 user_provider: Option<UserProviderRef>,
65 process_manager: Option<ProcessManagerRef>,
66 ) -> PostgresServer {
67 let make_handler = Arc::new(
68 MakePostgresServerHandlerBuilder::default()
69 .query_handler(query_handler.clone())
70 .copy_in_handler(copy_in_handler)
71 .user_provider(user_provider.clone())
72 .force_tls(force_tls)
73 .build()
74 .unwrap(),
75 );
76 PostgresServer {
77 base_server: BaseTcpServer::create_server("Postgres", io_runtime),
78 make_handler,
79 tls_server_config,
80 keep_alive_secs,
81 batching_enabled: false,
82 influxdb_handler: None,
83 bind_addr: None,
84 process_manager,
85 }
86 }
87
88 pub fn with_batching_enabled(mut self, enabled: bool) -> Self {
90 self.batching_enabled = enabled;
91 self
92 }
93
94 pub fn with_influxdb_handler(mut self, handler: InfluxdbLineProtocolHandlerRef) -> Self {
99 self.influxdb_handler = Some(handler);
100 self
101 }
102
103 fn accept(
104 &self,
105 io_runtime: Runtime,
106 accepting_stream: AbortableStream,
107 ) -> impl Future<Output = ()> + use<> {
108 let make_handler = &self.make_handler;
114 let handler_maker = Arc::new(MakePostgresServerHandler {
115 query_handler: make_handler.query_handler.clone(),
116 copy_in_handler: make_handler.copy_in_handler.clone(),
117 influxdb_handler: self.influxdb_handler.clone(),
118 user_provider: make_handler.user_provider.clone(),
119 param_provider: make_handler.param_provider.clone(),
120 force_tls: make_handler.force_tls,
121 });
122 let batching_enabled = self.batching_enabled;
123 let tls_server_config = self.tls_server_config.clone();
124 let process_manager = self.process_manager.clone();
125 accepting_stream.for_each(move |tcp_stream| {
126 let io_runtime = io_runtime.clone();
127 let tls_acceptor = tls_server_config.get_config().map(TlsAcceptor::from);
128 let handler_maker = handler_maker.clone();
129 let process_id = process_manager.as_ref().map(|p| p.next_id()).unwrap_or(0);
130
131 async move {
132 match tcp_stream {
133 Err(error) => debug!("Broken pipe: {}", error), Ok(io_stream) => {
135 let addr = match io_stream.peer_addr() {
136 Ok(addr) => {
137 debug!("PostgreSQL client coming from {}", addr);
138 Some(addr)
139 }
140 Err(e) => {
141 warn!(e; "Failed to get PostgreSQL client addr");
142 None
143 }
144 };
145
146 let _handle = io_runtime.spawn(async move {
147 crate::metrics::METRIC_POSTGRES_CONNECTIONS.inc();
148 let pg_handler =
149 Arc::new(handler_maker.make(addr, process_id, batching_enabled));
150 let r =
151 process_socket(io_stream, tls_acceptor.clone(), pg_handler).await;
152 crate::metrics::METRIC_POSTGRES_CONNECTIONS.dec();
153 r
154 });
155 }
156 };
157 }
158 })
159 }
160}
161
162pub const POSTGRES_SERVER: &str = "POSTGRES_SERVER";
163
164#[async_trait]
165impl Server for PostgresServer {
166 async fn shutdown(&self) -> Result<()> {
167 self.base_server.shutdown().await
168 }
169
170 async fn start(&mut self, listening: SocketAddr) -> Result<()> {
171 let (stream, addr) = self
172 .base_server
173 .bind(listening, self.keep_alive_secs)
174 .await?;
175
176 let io_runtime = self.base_server.io_runtime();
177 let join_handle = common_runtime::spawn_global(self.accept(io_runtime, stream));
178
179 self.base_server.start_with(join_handle).await?;
180
181 self.bind_addr = Some(addr);
182 Ok(())
183 }
184
185 fn name(&self) -> &str {
186 POSTGRES_SERVER
187 }
188
189 fn bind_addr(&self) -> Option<SocketAddr> {
190 self.bind_addr
191 }
192
193 fn as_any(&self) -> &dyn Any {
194 self
195 }
196}