store_api/manifest/
action.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//! Common actions for manifest
16use serde::{Deserialize, Serialize};
17
18use crate::manifest::ManifestVersion;
19
20pub type ProtocolVersion = u16;
21
22/// Current reader and writer versions
23/// TODO(dennis): configurable
24const READER_VERSION: ProtocolVersion = 0;
25const WRITER_VERSION: ProtocolVersion = 0;
26
27/// The maximum protocol version we are currently allowed to use,
28/// TODO(dennis): reading from configuration.
29pub fn supported_protocol_version() -> (ProtocolVersion, ProtocolVersion) {
30    (READER_VERSION, WRITER_VERSION)
31}
32
33/// Protocol action that used to block older clients from reading or writing the log when backwards
34/// incompatible changes are made to the protocol.
35///
36/// clients should be tolerant of messages and fields that they do not understand.
37#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
38pub struct ProtocolAction {
39    pub min_reader_version: ProtocolVersion,
40    pub min_writer_version: ProtocolVersion,
41}
42
43impl std::fmt::Display for ProtocolAction {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        write!(
46            f,
47            "Protocol({}, {})",
48            &self.min_reader_version, &self.min_writer_version,
49        )
50    }
51}
52
53#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
54pub struct VersionHeader {
55    pub prev_version: ManifestVersion,
56}
57
58impl Default for ProtocolAction {
59    fn default() -> Self {
60        let (min_reader_version, min_writer_version) = supported_protocol_version();
61        Self {
62            min_reader_version,
63            min_writer_version,
64        }
65    }
66}
67
68impl ProtocolAction {
69    pub fn new() -> Self {
70        Self::default()
71    }
72
73    pub fn is_readable(&self, reader_version: ProtocolVersion) -> bool {
74        reader_version >= self.min_reader_version
75    }
76
77    pub fn is_writable(&self, writer_version: ProtocolVersion) -> bool {
78        writer_version >= self.min_writer_version
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use serde_json as json;
85
86    use super::*;
87
88    #[test]
89    fn test_protocol_action() {
90        let mut action = ProtocolAction::new();
91
92        assert!(action.is_readable(0));
93        assert!(action.is_writable(0));
94        action.min_reader_version = 2;
95        action.min_writer_version = 3;
96        assert!(!action.is_readable(0));
97        assert!(!action.is_writable(0));
98        assert!(action.is_readable(2));
99        assert!(action.is_writable(3));
100        assert!(action.is_readable(3));
101        assert!(action.is_writable(4));
102
103        let s = json::to_string(&action).unwrap();
104        assert_eq!("{\"min_reader_version\":2,\"min_writer_version\":3}", s);
105
106        let action_decoded: ProtocolAction = json::from_str(&s).unwrap();
107        assert!(!action_decoded.is_readable(0));
108        assert!(!action_decoded.is_writable(0));
109        assert!(action_decoded.is_readable(2));
110        assert!(action_decoded.is_writable(3));
111        assert!(action_decoded.is_readable(3));
112        assert!(action_decoded.is_writable(4));
113    }
114}