meta_srv/election/
rds.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#[cfg(feature = "mysql_kvbackend")]
16pub mod mysql;
17#[cfg(feature = "pg_kvbackend")]
18pub mod postgres;
19
20use common_time::Timestamp;
21use itertools::Itertools;
22use snafu::OptionExt;
23
24use crate::election::LeaderKey;
25use crate::error::{Result, UnexpectedSnafu};
26
27// Separator between value and expire time in the lease string.
28// A lease is put into rds election in the format:
29// <node_info> || __metadata_lease_sep || <expire_time>
30const LEASE_SEP: &str = r#"||__metadata_lease_sep||"#;
31
32/// Parses the value and expire time from the given string retrieved from rds.
33fn parse_value_and_expire_time(value: &str) -> Result<(String, Timestamp)> {
34    let (value, expire_time) =
35        value
36            .split(LEASE_SEP)
37            .collect_tuple()
38            .with_context(|| UnexpectedSnafu {
39                violated: format!(
40                    "Invalid value {}, expect node info || {} || expire time",
41                    value, LEASE_SEP
42                ),
43            })?;
44    // Given expire_time is in the format 'YYYY-MM-DD HH24:MI:SS.MS'
45    let expire_time = match Timestamp::from_str(expire_time, None) {
46        Ok(ts) => ts,
47        Err(_) => UnexpectedSnafu {
48            violated: format!("Invalid timestamp: {}", expire_time),
49        }
50        .fail()?,
51    };
52    Ok((value.to_string(), expire_time))
53}
54
55/// LeaderKey used for [LeaderChangeMessage] in rds election components.
56#[derive(Debug, Clone, Default)]
57struct RdsLeaderKey {
58    name: Vec<u8>,
59    key: Vec<u8>,
60    rev: i64,
61    lease: i64,
62}
63
64impl LeaderKey for RdsLeaderKey {
65    fn name(&self) -> &[u8] {
66        &self.name
67    }
68
69    fn key(&self) -> &[u8] {
70        &self.key
71    }
72
73    fn revision(&self) -> i64 {
74        self.rev
75    }
76
77    fn lease_id(&self) -> i64 {
78        self.lease
79    }
80}
81
82/// Lease information for rds election.
83#[derive(Default, Clone, Debug)]
84struct Lease {
85    leader_value: String,
86    expire_time: Timestamp,
87    current: Timestamp,
88    // `origin` is the original value of the lease, used for CAS.
89    origin: String,
90}