Skip to main content

typedb_driver/connection/server/
mod.rs

1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *   http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20pub(crate) mod server_connection;
21pub(crate) mod server_manager;
22pub mod server_routing;
23pub mod server_version;
24
25use crate::common::address::{Address, address_translation::AddressTranslation};
26
27pub const DEFAULT_SERVER_ID: u64 = 0;
28
29pub trait Replica: Clone {
30    /// Returns the id of this replica. 0 (default) if it's not a part of a cluster.
31    fn id(&self) -> u64;
32
33    /// Returns whether this is the primary replica of the cluster or any of the supporting roles.
34    fn role(&self) -> Option<ReplicationRole>;
35
36    /// Checks whether this is the primary replica of the cluster.
37    fn is_primary(&self) -> bool;
38
39    /// Returns the cluster protocol 'term' of this replica.
40    fn term(&self) -> Option<u64>;
41}
42
43/// The metadata and state of an individual server of a driver connection.
44#[derive(Debug, Clone, Eq, PartialEq, Hash)]
45pub enum Server {
46    Available(AvailableServer),
47    Unavailable { replication_status: Option<ReplicationStatus> },
48}
49
50impl Server {
51    pub(crate) fn available_from_private(
52        private_address: Address,
53        replication_status: Option<ReplicationStatus>,
54    ) -> Self {
55        Self::Available(AvailableServer::from_private(private_address, replication_status))
56    }
57
58    pub(crate) fn translate_address(&mut self, address_translation: &AddressTranslation) {
59        match self {
60            Server::Available(available) => available.translate_address(address_translation),
61            Server::Unavailable { .. } => {}
62        }
63    }
64
65    pub(crate) fn translated(mut self, address_translation: &AddressTranslation) -> Self {
66        self.translate_address(address_translation);
67        self
68    }
69
70    pub(crate) fn replication_status(&self) -> &Option<ReplicationStatus> {
71        match self {
72            Server::Available(available_server) => available_server.replication_status(),
73            Server::Unavailable { replication_status } => replication_status,
74        }
75    }
76
77    /// Returns the address this server is hosted at. None if the information is unavailable.
78    pub fn address(&self) -> Option<&Address> {
79        match self {
80            Server::Available(available_server) => Some(available_server.address()),
81            Server::Unavailable { .. } => None,
82        }
83    }
84}
85
86impl Replica for Server {
87    /// Returns the id of this replica. 0 (default) if it's not a part of a cluster.
88    fn id(&self) -> u64 {
89        self.replication_status().map(|status| status.id).unwrap_or(DEFAULT_SERVER_ID)
90    }
91
92    /// Returns whether this is the primary replica of the cluster or any of the supporting roles.
93    fn role(&self) -> Option<ReplicationRole> {
94        self.replication_status().map(|status| status.role).flatten()
95    }
96
97    /// Checks whether this is the primary replica of the cluster.
98    fn is_primary(&self) -> bool {
99        matches!(self.role(), Some(ReplicationRole::Primary))
100    }
101
102    /// Returns the cluster protocol 'term' of this replica.
103    fn term(&self) -> Option<u64> {
104        self.replication_status().map(|status| status.term).flatten()
105    }
106}
107
108/// A specialization of an available `Server` with a known connection address.
109#[derive(Debug, Clone, Eq, PartialEq, Hash)]
110pub struct AvailableServer {
111    private_address: Address,
112    public_address: Option<Address>,
113    replication_status: Option<ReplicationStatus>,
114}
115
116impl AvailableServer {
117    pub(crate) fn from_private(private_address: Address, replication_status: Option<ReplicationStatus>) -> Self {
118        Self { private_address, public_address: None, replication_status }
119    }
120
121    pub(crate) fn translate_address(&mut self, address_translation: &AddressTranslation) {
122        if let Some(translated) = address_translation.to_public(&self.private_address) {
123            self.public_address = Some(translated);
124        }
125    }
126
127    pub(crate) fn translated(mut self, address_translation: &AddressTranslation) -> Self {
128        self.translate_address(address_translation);
129        self
130    }
131
132    pub(crate) fn private_address(&self) -> &Address {
133        &self.private_address
134    }
135
136    pub(crate) fn replication_status(&self) -> &Option<ReplicationStatus> {
137        &self.replication_status
138    }
139
140    /// Returns the address this server is hosted at.
141    pub fn address(&self) -> &Address {
142        self.public_address.as_ref().unwrap_or_else(|| &self.private_address)
143    }
144}
145
146impl Replica for AvailableServer {
147    /// Returns the id of this replica. 0 (default) if it's not a part of a cluster.
148    fn id(&self) -> u64 {
149        self.replication_status().map(|status| status.id).unwrap_or(DEFAULT_SERVER_ID)
150    }
151
152    /// Returns whether this is the primary replica of the cluster or any of the supporting roles.
153    fn role(&self) -> Option<ReplicationRole> {
154        self.replication_status().map(|status| status.role).flatten()
155    }
156
157    /// Checks whether this is the primary replica of the cluster.
158    fn is_primary(&self) -> bool {
159        matches!(self.role(), Some(ReplicationRole::Primary))
160    }
161
162    /// Returns the cluster protocol 'term' of this replica.
163    fn term(&self) -> Option<u64> {
164        self.replication_status().map(|status| status.term).flatten()
165    }
166}
167
168/// The replication metadata and state of an individual server as a cluster replica.
169#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
170pub struct ReplicationStatus {
171    /// The id of this replica.
172    pub(crate) id: u64,
173    /// The role of this replica in the cluster. May be unknown when the server is unavailable.
174    pub(crate) role: Option<ReplicationRole>,
175    /// The cluster protocol 'term' of this server. May be unknown when the server is unavailable.
176    pub(crate) term: Option<u64>,
177}
178
179impl Default for ReplicationStatus {
180    fn default() -> Self {
181        Self { id: DEFAULT_SERVER_ID, role: None, term: None }
182    }
183}
184
185/// This enum is used to specify the replication role of a server.
186#[repr(C)]
187#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
188pub enum ReplicationRole {
189    /// The primary (leader) server in a replicated cluster.
190    Primary,
191    /// A candidate server eligible for promotion to primary.
192    Candidate,
193    /// A secondary (follower) server.
194    Secondary,
195}