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}