common_meta/
peer.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
17pub use api::v1::meta::Peer;
18use api::v1::meta::heartbeat_request::NodeWorkloads;
19
20use crate::error::Error;
21use crate::{DatanodeId, FlownodeId};
22
23/// [`PeerResolver`] provides methods to look up peer information by node ID.
24///
25/// This trait allows resolving both datanode and flownode peers, regardless of their current activity status.
26/// Returned peers may be inactive (i.e., not currently alive in the cluster).
27#[async_trait::async_trait]
28pub trait PeerResolver: Send + Sync {
29    /// Looks up a datanode peer by its ID.
30    ///
31    /// Returns `Some(Peer)` if the datanode exists, or `None` if not found.
32    /// The returned peer may be inactive.
33    async fn datanode(&self, id: DatanodeId) -> Result<Option<Peer>, Error>;
34
35    /// Looks up a flownode peer by its ID.
36    ///
37    /// Returns `Some(Peer)` if the flownode exists, or `None` if not found.
38    /// The returned peer may be inactive.
39    async fn flownode(&self, id: FlownodeId) -> Result<Option<Peer>, Error>;
40}
41
42pub type PeerResolverRef = Arc<dyn PeerResolver>;
43
44/// [`PeerDiscovery`] is a service for discovering active peers in the cluster.
45#[async_trait::async_trait]
46pub trait PeerDiscovery: Send + Sync {
47    /// Returns all currently active frontend nodes.
48    ///
49    /// A frontend is considered active if it has reported a heartbeat within the most recent heartbeat interval,
50    /// as determined by the in-memory backend.
51    async fn active_frontends(&self) -> Result<Vec<Peer>, Error>;
52
53    /// Returns all currently active datanodes, optionally filtered by a predicate on their workloads.
54    ///
55    /// A datanode is considered active if it has reported a heartbeat within the most recent heartbeat interval,
56    /// as determined by the in-memory backend.
57    /// The optional `filter` allows further selection based on the node's workloads.
58    async fn active_datanodes(
59        &self,
60        filter: Option<for<'a> fn(&'a NodeWorkloads) -> bool>,
61    ) -> Result<Vec<Peer>, Error>;
62
63    /// Returns all currently active flownodes, optionally filtered by a predicate on their workloads.
64    ///
65    /// A flownode is considered active if it has reported a heartbeat within the most recent heartbeat interval,
66    /// as determined by the in-memory backend.
67    /// The optional `filter` allows further selection based on the node's workloads.
68    async fn active_flownodes(
69        &self,
70        filter: Option<for<'a> fn(&'a NodeWorkloads) -> bool>,
71    ) -> Result<Vec<Peer>, Error>;
72}
73
74pub type PeerDiscoveryRef = Arc<dyn PeerDiscovery>;
75
76/// [`PeerAllocator`] allocates [`Peer`]s for creating region or flow.
77#[async_trait::async_trait]
78pub trait PeerAllocator: Send + Sync {
79    async fn alloc(&self, num: usize) -> Result<Vec<Peer>, Error>;
80}
81
82pub type PeerAllocatorRef = Arc<dyn PeerAllocator>;
83
84pub struct NoopPeerAllocator;
85
86#[async_trait::async_trait]
87impl PeerAllocator for NoopPeerAllocator {
88    async fn alloc(&self, num: usize) -> Result<Vec<Peer>, Error> {
89        Ok(vec![Peer::default(); num])
90    }
91}