openstack_keystone_distributed_storage/proto_impl/impl_leader_id.rs
1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12//
13// SPDX-License-Identifier: Apache-2.0
14//! # Implement [`RaftLeaderId`] for protobuf defined LeaderId, so that it can be used in OpenRaft
15
16use std::cmp::Ordering;
17use std::fmt;
18
19use openraft::vote::LeaderIdCompare;
20use openraft::vote::RaftLeaderId;
21
22use crate::TypeConfig;
23use crate::protobuf as pb;
24
25/// Implements PartialOrd for LeaderId to enforce the standard Raft behavior of
26/// at most one leader per term.
27///
28/// In standard Raft, each term can have at most one leader. This is enforced by
29/// making leader IDs with the same term incomparable (returning None), unless
30/// they refer to the same node.
31///
32/// This differs from the [`PartialOrd`] default implementation which would
33/// allow multiple leaders in the same term by comparing node IDs.
34impl PartialOrd for pb::raft::LeaderId {
35 #[inline]
36 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
37 LeaderIdCompare::std(self, other)
38 }
39}
40
41impl PartialEq<u64> for pb::raft::LeaderId {
42 fn eq(&self, _other: &u64) -> bool {
43 false
44 }
45}
46
47impl PartialOrd<u64> for pb::raft::LeaderId {
48 fn partial_cmp(&self, other: &u64) -> Option<Ordering> {
49 self.term.partial_cmp(other)
50 }
51}
52
53impl fmt::Display for pb::raft::LeaderId {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 write!(f, "T{}-N{}", self.term, self.node_id)
56 }
57}
58
59impl RaftLeaderId<TypeConfig> for pb::raft::LeaderId {
60 type Committed = u64;
61
62 fn new(term: u64, node_id: u64) -> Self {
63 Self { term, node_id }
64 }
65
66 fn term(&self) -> u64 {
67 self.term
68 }
69
70 fn node_id(&self) -> &u64 {
71 &self.node_id
72 }
73
74 fn to_committed(&self) -> Self::Committed {
75 self.term
76 }
77}