1use std::net::SocketAddr;
18use std::sync::Arc;
19
20use api::v1::flow::DirtyWindowRequests;
21use catalog::CatalogManagerRef;
22use common_base::Plugins;
23use common_error::ext::BoxedError;
24use common_meta::key::TableMetadataManagerRef;
25use common_meta::key::flow::FlowMetadataManagerRef;
26use common_meta::node_manager::Flownode;
27use futures::TryStreamExt;
28use greptime_proto::v1::flow::{FlowRequest, FlowResponse, InsertRequests, flow_server};
29use itertools::Itertools;
30use query::QueryEngineFactory;
31use servers::add_service;
32use servers::grpc::builder::GrpcServerBuilder;
33use servers::grpc::{GrpcServer, GrpcServerConfig};
34use servers::http::HttpServerBuilder;
35use servers::metrics_handler::MetricsHandler;
36use servers::server::{ServerHandler, ServerHandlers};
37use snafu::ResultExt;
38use tonic::codec::CompressionEncoding;
39use tonic::{Request, Response, Status};
40
41use crate::adapter::flownode_impl::{FlowDualEngine, FlowDualEngineRef};
42use crate::batching_mode::engine::BatchingEngine;
43use crate::error::{
44 DatafusionSnafu, ExternalSnafu, ListFlowsSnafu, ParseAddrSnafu, ShutdownServerSnafu,
45 StartServerSnafu, to_status_with_last_err,
46};
47use crate::heartbeat::HeartbeatTask;
48use crate::metrics::{METRIC_FLOW_PROCESSING_TIME, METRIC_FLOW_ROWS};
49use crate::utils::{SizeReportSender, StateReportHandler};
50use crate::{BatchingExecutionFactory, Error, FlownodeOptions, FrontendClient, StreamingEngine};
51
52pub const FLOW_NODE_SERVER_NAME: &str = "FLOW_NODE_SERVER";
53#[derive(Clone)]
55pub struct FlowService {
56 pub dual_engine: FlowDualEngineRef,
57}
58
59impl FlowService {
60 pub fn new(manager: FlowDualEngineRef) -> Self {
61 Self {
62 dual_engine: manager,
63 }
64 }
65}
66
67#[async_trait::async_trait]
68impl flow_server::Flow for FlowService {
69 async fn handle_create_remove(
70 &self,
71 request: Request<FlowRequest>,
72 ) -> Result<Response<FlowResponse>, Status> {
73 let _timer = METRIC_FLOW_PROCESSING_TIME
74 .with_label_values(&["ddl"])
75 .start_timer();
76
77 let request = request.into_inner();
78 self.dual_engine
79 .handle(request)
80 .await
81 .map_err(|err| {
82 common_telemetry::error!(err; "Failed to handle flow request");
83 err
84 })
85 .map(Response::new)
86 .map_err(to_status_with_last_err)
87 }
88
89 async fn handle_mirror_request(
90 &self,
91 request: Request<InsertRequests>,
92 ) -> Result<Response<FlowResponse>, Status> {
93 let _timer = METRIC_FLOW_PROCESSING_TIME
94 .with_label_values(&["insert"])
95 .start_timer();
96
97 let request = request.into_inner();
98 let mut row_count = 0;
100 let request = api::v1::region::InsertRequests {
101 requests: request
102 .requests
103 .into_iter()
104 .map(|insert| {
105 insert.rows.as_ref().inspect(|x| row_count += x.rows.len());
106 api::v1::region::InsertRequest {
107 region_id: insert.region_id,
108 rows: insert.rows,
109 skip_wal: false,
110 partition_expr_version: insert.partition_expr_version,
111 }
112 })
113 .collect_vec(),
114 };
115
116 METRIC_FLOW_ROWS
117 .with_label_values(&["in"])
118 .inc_by(row_count as u64);
119
120 self.dual_engine
121 .handle_inserts(request)
122 .await
123 .map(Response::new)
124 .map_err(to_status_with_last_err)
125 }
126
127 async fn handle_mark_dirty_time_window(
128 &self,
129 reqs: Request<DirtyWindowRequests>,
130 ) -> Result<Response<FlowResponse>, Status> {
131 self.dual_engine
132 .handle_mark_window_dirty(reqs.into_inner())
133 .await
134 .map(Response::new)
135 .map_err(to_status_with_last_err)
136 }
137}
138
139#[derive(Clone)]
140pub struct FlownodeServer {
141 inner: Arc<FlownodeServerInner>,
142}
143
144struct FlownodeServerInner {
148 flow_service: FlowService,
149}
150
151impl FlownodeServer {
152 pub fn new(flow_service: FlowService) -> Self {
153 Self {
154 inner: Arc::new(FlownodeServerInner { flow_service }),
155 }
156 }
157}
158
159impl FlownodeServer {
160 pub fn create_flow_service(&self) -> flow_server::FlowServer<impl flow_server::Flow> {
161 flow_server::FlowServer::new(self.inner.flow_service.clone())
162 .accept_compressed(CompressionEncoding::Gzip)
163 .send_compressed(CompressionEncoding::Gzip)
164 .accept_compressed(CompressionEncoding::Zstd)
165 .send_compressed(CompressionEncoding::Zstd)
166 }
167}
168
169pub struct FlownodeInstance {
171 flownode_server: FlownodeServer,
172 services: ServerHandlers,
173 heartbeat_task: Option<HeartbeatTask>,
174 state_report_task: Option<common_runtime::JoinHandle<()>>,
175 consistent_check_task_started: bool,
176}
177
178impl FlownodeInstance {
179 pub async fn start(&mut self) -> Result<(), crate::Error> {
180 if let Some(task) = &self.heartbeat_task {
181 task.start().await?;
182 }
183
184 let engine = self.flow_engine();
185 if self.state_report_task.is_none() {
188 self.state_report_task = engine.clone().start_state_report_task().await;
189 }
190 if let Err(err) = engine.start_flow_consistent_check_task().await {
191 self.rollback_background_tasks().await;
192 return Err(err);
193 }
194 self.consistent_check_task_started = true;
195
196 if let Err(err) = self.services.start_all().await.context(StartServerSnafu) {
197 self.rollback_background_tasks().await;
198 return Err(err);
199 }
200
201 Ok(())
202 }
203 pub async fn shutdown(&mut self) -> Result<(), Error> {
204 let services_result = self
205 .services
206 .shutdown_all()
207 .await
208 .context(ShutdownServerSnafu);
209 let tasks_result = self.stop_background_tasks().await;
210
211 services_result?;
212 tasks_result?;
213 Ok(())
214 }
215
216 async fn stop_background_tasks(&mut self) -> Result<(), Error> {
217 let check_result = if self.consistent_check_task_started {
218 self.consistent_check_task_started = false;
219 self.flow_engine().stop_flow_consistent_check_task().await
220 } else {
221 Ok(())
222 };
223
224 if let Some(task) = &self.heartbeat_task {
225 task.shutdown();
226 }
227
228 check_result
229 }
230
231 async fn rollback_background_tasks(&mut self) {
232 if let Err(err) = self.stop_background_tasks().await {
233 common_telemetry::error!(err; "Failed to roll back flownode background tasks");
234 }
235 }
236
237 pub fn flownode_server(&self) -> &FlownodeServer {
238 &self.flownode_server
239 }
240
241 pub fn flow_engine(&self) -> FlowDualEngineRef {
242 self.flownode_server.inner.flow_service.dual_engine.clone()
243 }
244
245 pub fn setup_services(&mut self, services: ServerHandlers) {
246 self.services = services;
247 }
248}
249
250pub struct FlownodeBuilder {
252 opts: FlownodeOptions,
253 plugins: Plugins,
254 table_meta: TableMetadataManagerRef,
255 catalog_manager: CatalogManagerRef,
256 flow_metadata_manager: FlowMetadataManagerRef,
257 heartbeat_task: Option<HeartbeatTask>,
258 state_report_handler: Option<StateReportHandler>,
260 frontend_client: Arc<FrontendClient>,
261}
262
263impl FlownodeBuilder {
264 pub fn new(
266 opts: FlownodeOptions,
267 plugins: Plugins,
268 table_meta: TableMetadataManagerRef,
269 catalog_manager: CatalogManagerRef,
270 flow_metadata_manager: FlowMetadataManagerRef,
271 frontend_client: Arc<FrontendClient>,
272 ) -> Self {
273 Self {
274 opts,
275 plugins,
276 table_meta,
277 catalog_manager,
278 flow_metadata_manager,
279 heartbeat_task: None,
280 state_report_handler: None,
281 frontend_client,
282 }
283 }
284
285 pub fn with_heartbeat_task(self, heartbeat_task: HeartbeatTask) -> Self {
286 let (sender, receiver) = SizeReportSender::new();
287 Self {
288 heartbeat_task: Some(heartbeat_task.with_query_stat_size(sender)),
289 state_report_handler: Some(receiver),
290 ..self
291 }
292 }
293
294 pub fn opts(&self) -> &FlownodeOptions {
295 &self.opts
296 }
297
298 pub fn table_meta(&self) -> &TableMetadataManagerRef {
299 &self.table_meta
300 }
301
302 pub fn catalog_manager(&self) -> &CatalogManagerRef {
303 &self.catalog_manager
304 }
305
306 pub fn flow_metadata_manager(&self) -> &FlowMetadataManagerRef {
307 &self.flow_metadata_manager
308 }
309
310 pub fn frontend_client(&self) -> &Arc<FrontendClient> {
311 &self.frontend_client
312 }
313
314 pub fn set_plugins(&mut self, plugins: Plugins) {
315 self.plugins = plugins;
316 }
317
318 pub async fn build(mut self) -> Result<FlownodeInstance, Error> {
319 let query_engine_factory = QueryEngineFactory::try_new_with_plugins(
321 self.catalog_manager.clone(),
323 None,
324 None,
325 None,
326 None,
327 None,
328 false,
329 Default::default(),
330 self.opts.query.clone(),
331 )
332 .context(DatafusionSnafu {
333 context: "Failed to build query engine",
334 })?;
335 let manager = Arc::new(self.build_manager(query_engine_factory.query_engine()));
336 let batching = Arc::new(BatchingEngine::new_with_execution(
337 self.frontend_client.clone(),
338 query_engine_factory.query_engine(),
339 self.flow_metadata_manager.clone(),
340 self.table_meta.clone(),
341 self.catalog_manager.clone(),
342 self.opts.flow.batching_mode.clone(),
343 self.plugins.get::<Arc<dyn BatchingExecutionFactory>>(),
344 ));
345 let dual = Arc::new(FlowDualEngine::new(
346 manager.clone(),
347 batching,
348 self.flow_metadata_manager.clone(),
349 self.catalog_manager.clone(),
350 self.plugins.clone(),
351 ));
352 if let Some(handler) = self.state_report_handler.take() {
353 dual.set_state_report_handler(handler).await;
354 }
355
356 let server = FlownodeServer::new(FlowService::new(dual));
357
358 let heartbeat_task = self.heartbeat_task;
359
360 let instance = FlownodeInstance {
361 flownode_server: server,
362 services: ServerHandlers::default(),
363 heartbeat_task,
364 state_report_task: None,
365 consistent_check_task_started: false,
366 };
367 Ok(instance)
368 }
369
370 fn build_manager(&self, query_engine: Arc<dyn query::QueryEngine>) -> StreamingEngine {
371 StreamingEngine::new(
372 self.opts.node_id.map(|id| id as u32),
373 query_engine,
374 self.table_meta.clone(),
375 self.frontend_client.clone(),
376 )
377 }
378}
379
380pub struct FlownodeServiceBuilder<'a> {
382 opts: &'a FlownodeOptions,
383 grpc_server: Option<GrpcServer>,
384 enable_http_service: bool,
385}
386
387impl<'a> FlownodeServiceBuilder<'a> {
388 pub fn new(opts: &'a FlownodeOptions) -> Self {
389 Self {
390 opts,
391 grpc_server: None,
392 enable_http_service: false,
393 }
394 }
395
396 pub fn enable_http_service(self) -> Self {
397 Self {
398 enable_http_service: true,
399 ..self
400 }
401 }
402
403 pub fn with_grpc_server(self, grpc_server: GrpcServer) -> Self {
404 Self {
405 grpc_server: Some(grpc_server),
406 ..self
407 }
408 }
409
410 pub fn with_default_grpc_server(mut self, flownode_server: &FlownodeServer) -> Self {
411 let grpc_server = Self::grpc_server_builder(self.opts, flownode_server).build();
412 self.grpc_server = Some(grpc_server);
413 self
414 }
415
416 pub fn build(mut self) -> Result<ServerHandlers, Error> {
417 let handlers = ServerHandlers::default();
418 if let Some(grpc_server) = self.grpc_server.take() {
419 let addr: SocketAddr = self.opts.grpc.bind_addr.parse().context(ParseAddrSnafu {
420 addr: &self.opts.grpc.bind_addr,
421 })?;
422 let handler: ServerHandler = (Box::new(grpc_server), addr);
423 handlers.insert(handler);
424 }
425
426 if self.enable_http_service {
427 let http_server = HttpServerBuilder::new(self.opts.http.clone())
428 .with_metrics_handler(MetricsHandler)
429 .build();
430 let addr: SocketAddr = self.opts.http.addr.parse().context(ParseAddrSnafu {
431 addr: &self.opts.http.addr,
432 })?;
433 let handler: ServerHandler = (Box::new(http_server), addr);
434 handlers.insert(handler);
435 }
436 Ok(handlers)
437 }
438
439 pub fn grpc_server_builder(
440 opts: &FlownodeOptions,
441 flownode_server: &FlownodeServer,
442 ) -> GrpcServerBuilder {
443 let config = GrpcServerConfig {
444 max_recv_message_size: opts.grpc.max_recv_message_size.as_bytes() as usize,
445 max_send_message_size: opts.grpc.max_send_message_size.as_bytes() as usize,
446 tls: opts.grpc.tls.clone(),
447 max_connection_age: opts.grpc.max_connection_age,
448 };
449 let service = flownode_server.create_flow_service();
450 let runtime = common_runtime::global_runtime();
451 let mut builder = GrpcServerBuilder::new(config, runtime);
452 add_service!(builder, service);
453 builder
454 }
455}
456
457pub(crate) async fn get_all_flow_ids(
459 flow_metadata_manager: &FlowMetadataManagerRef,
460 catalog_manager: &CatalogManagerRef,
461 nodeid: Option<u64>,
462) -> Result<Vec<u32>, Error> {
463 let ret = if let Some(nodeid) = nodeid {
464 let flow_ids_one_node = flow_metadata_manager
465 .flownode_flow_manager()
466 .flows(nodeid)
467 .try_collect::<Vec<_>>()
468 .await
469 .context(ListFlowsSnafu { id: Some(nodeid) })?;
470 flow_ids_one_node.into_iter().map(|(id, _)| id).collect()
471 } else {
472 let all_catalogs = catalog_manager
473 .catalog_names()
474 .await
475 .map_err(BoxedError::new)
476 .context(ExternalSnafu)?;
477 let mut all_flow_ids = vec![];
478 for catalog in all_catalogs {
479 let flows = flow_metadata_manager
480 .flow_name_manager()
481 .flow_names(&catalog)
482 .await
483 .try_collect::<Vec<_>>()
484 .await
485 .map_err(BoxedError::new)
486 .context(ExternalSnafu)?;
487
488 all_flow_ids.extend(flows.into_iter().map(|(_, id)| id.flow_id()));
489 }
490 all_flow_ids
491 };
492
493 Ok(ret)
494}
495
496#[cfg(test)]
497mod tests {
498 use std::sync::Arc;
499
500 use catalog::memory::new_memory_catalog_manager;
501 use common_base::Plugins;
502 use common_meta::key::TableMetadataManager;
503 use common_meta::key::flow::FlowMetadataManager;
504 use common_meta::kv_backend::memory::MemoryKvBackend;
505 use query::options::QueryOptions;
506
507 use super::*;
508 use crate::batching_mode::BatchingModeOptions;
509
510 async fn new_test_flownode_server() -> (FlownodeServer, SizeReportSender) {
511 let (frontend_client, _handler) =
512 FrontendClient::from_empty_grpc_handler(QueryOptions::default());
513
514 new_test_flownode_server_with_frontend_client(
515 frontend_client,
516 BatchingModeOptions::default(),
517 None,
518 )
519 .await
520 }
521
522 async fn new_test_flownode_server_with_frontend_client(
523 frontend_client: FrontendClient,
524 batching_opts: BatchingModeOptions,
525 node_id: Option<u32>,
526 ) -> (FlownodeServer, SizeReportSender) {
527 let kv_backend = Arc::new(MemoryKvBackend::new());
528 let table_meta = Arc::new(TableMetadataManager::new(kv_backend.clone()));
529 table_meta.init().await.unwrap();
530 let flow_meta = Arc::new(FlowMetadataManager::new(kv_backend.clone()));
531 let catalog_manager = new_memory_catalog_manager().unwrap();
532 let query_engine = crate::test_utils::create_test_query_engine();
533
534 let frontend_client = Arc::new(frontend_client);
535 let streaming_engine = Arc::new(StreamingEngine::new(
536 node_id,
537 query_engine.clone(),
538 table_meta.clone(),
539 frontend_client.clone(),
540 ));
541 let batching_engine = Arc::new(BatchingEngine::new(
542 frontend_client,
543 query_engine,
544 flow_meta.clone(),
545 table_meta,
546 catalog_manager.clone(),
547 batching_opts,
548 ));
549 let dual_engine = Arc::new(FlowDualEngine::new(
550 streaming_engine,
551 batching_engine,
552 flow_meta,
553 catalog_manager,
554 Plugins::new(),
555 ));
556
557 let (report_sender, report_handler) = SizeReportSender::new();
558 dual_engine.set_state_report_handler(report_handler).await;
559
560 let server = FlownodeServer::new(FlowService::new(dual_engine));
561 (server, report_sender)
562 }
563}