Skip to main content

datanode/
region_query.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
15//! The datanode's [`RegionQueryHandler`] implementation for querying remote regions in a
16//! `MergeScan` plan.
17
18use std::sync::Arc;
19
20use api::v1::region::{RemoteDynFilterUnregister, RemoteDynFilterUpdate};
21use async_trait::async_trait;
22use common_error::ext::BoxedError;
23use common_meta::node_manager::NodeManagerRef;
24use common_query::request::QueryRequest;
25use common_recordbatch::SendableRecordBatchStream;
26use partition::manager::PartitionRuleManagerRef;
27use query::error::{RegionQuerySnafu, Result as QueryResult, UnimplementedSnafu};
28use query::region_query::{RegionQueryHandler, RegionQueryTarget};
29use session::ReadPreference;
30use snafu::ResultExt;
31use store_api::storage::RegionId;
32
33/// Serves region queries by resolving their leader and forwarding requests to its datanode.
34pub(crate) struct DatanodeRegionQueryHandler {
35    partition_manager: PartitionRuleManagerRef,
36    node_manager: NodeManagerRef,
37}
38
39impl DatanodeRegionQueryHandler {
40    pub fn arc(
41        partition_manager: PartitionRuleManagerRef,
42        node_manager: NodeManagerRef,
43    ) -> Arc<Self> {
44        Arc::new(Self {
45            partition_manager,
46            node_manager,
47        })
48    }
49}
50
51#[async_trait]
52impl RegionQueryHandler for DatanodeRegionQueryHandler {
53    async fn select_target(
54        &self,
55        _read_preference: ReadPreference,
56        region_id: RegionId,
57    ) -> QueryResult<RegionQueryTarget> {
58        // The leader of a region is the only peer that can serve a region query.
59        //
60        let peer = self
61            .partition_manager
62            .find_region_leader(region_id)
63            .await
64            .map_err(BoxedError::new)
65            .context(RegionQuerySnafu)?;
66
67        Ok(RegionQueryTarget::new(peer))
68    }
69
70    async fn do_get(
71        &self,
72        target: &RegionQueryTarget,
73        request: QueryRequest,
74    ) -> QueryResult<SendableRecordBatchStream> {
75        self.node_manager
76            .datanode(target.peer())
77            .await
78            .handle_query(request)
79            .await
80            .map_err(BoxedError::new)
81            .context(RegionQuerySnafu)
82    }
83
84    /// Datanodes forward received region queries and do not produce remote dynamic filters.
85    async fn handle_remote_dyn_filter_update(
86        &self,
87        _target: &RegionQueryTarget,
88        _query_id: String,
89        _update: RemoteDynFilterUpdate,
90    ) -> QueryResult<()> {
91        UnimplementedSnafu {
92            operation: "remote dynamic filter update from a datanode",
93        }
94        .fail()
95    }
96
97    /// See [`RegionQueryHandler::handle_remote_dyn_filter_update`].
98    async fn handle_remote_dyn_filter_unregister(
99        &self,
100        _target: &RegionQueryTarget,
101        _query_id: String,
102        _unregister: RemoteDynFilterUnregister,
103    ) -> QueryResult<()> {
104        UnimplementedSnafu {
105            operation: "remote dynamic filter unregister from a datanode",
106        }
107        .fail()
108    }
109}