risingwave_common/system_param/
reader.rs

1// Copyright 2023 RisingWave Labs
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::borrow::Borrow;
16
17use risingwave_license::LicenseKeyRef;
18use risingwave_pb::meta::PbSystemParams;
19
20use super::{ParamValue, default};
21use crate::for_all_params;
22
23/// Information about a system parameter.
24///
25/// Used to display to users through `pg_settings` system table and `SHOW PARAMETERS` command.
26pub struct ParameterInfo {
27    pub name: &'static str,
28    pub mutable: bool,
29    /// The [`ToString`] representation of the parameter value.
30    ///
31    /// Certain parameters, such as `license_key`, may be sensitive, and redaction is applied to them in their newtypes.
32    /// As a result, we get the redacted value here for display.
33    pub value: String,
34    pub description: &'static str,
35}
36
37macro_rules! define_system_params_read_trait {
38    ($({ $field:ident, $type:ty, $default:expr, $is_mutable:expr, $doc:literal, $($rest:tt)* },)*) => {
39        /// The trait delegating reads on [`risingwave_pb::meta::SystemParams`].
40        ///
41        /// Purposes:
42        /// - Avoid misuse of deprecated fields by hiding their getters.
43        /// - Abstract fallback logic for fields that might not be provided by meta service due to backward
44        ///   compatibility.
45        /// - Redact sensitive fields by returning a newtype around the original value.
46        pub trait SystemParamsRead {
47            $(
48                #[doc = $doc]
49                fn $field(&self) -> <$type as ParamValue>::Borrowed<'_>;
50            )*
51
52            /// Return the information of all parameters.
53            fn get_all(&self) -> Vec<ParameterInfo> {
54                vec![
55                    $(
56                        ParameterInfo {
57                            name: stringify!($field),
58                            mutable: $is_mutable,
59                            value: self.$field().to_string(), // use `to_string` to get displayable (maybe redacted) value
60                            description: $doc,
61                        },
62                    )*
63                ]
64            }
65        }
66    };
67}
68
69for_all_params!(define_system_params_read_trait);
70
71/// The wrapper delegating reads on [`risingwave_pb::meta::SystemParams`].
72///
73/// See [`SystemParamsRead`] for more details.
74// TODO: should we manually impl `PartialEq` by comparing each field with read functions?
75#[derive(Clone, PartialEq)]
76pub struct SystemParamsReader<I = PbSystemParams> {
77    inner: I,
78}
79
80// TODO: should ban `Debug` for inner `SystemParams`.
81// https://github.com/risingwavelabs/risingwave/pull/17906#discussion_r1705056943
82macro_rules! impl_system_params_reader_debug {
83    ($({ $field:ident, $($rest:tt)* },)*) => {
84        impl<I> std::fmt::Debug for SystemParamsReader<I>
85        where
86            I: Borrow<PbSystemParams>,
87        {
88            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89                f.debug_struct("SystemParamsReader")
90                    $(
91                        .field(stringify!($field), &self.$field())
92                    )*
93                    .finish()
94            }
95        }
96    };
97}
98
99for_all_params!(impl_system_params_reader_debug);
100
101impl<I> From<I> for SystemParamsReader<I>
102where
103    I: Borrow<PbSystemParams>,
104{
105    fn from(inner: I) -> Self {
106        Self { inner }
107    }
108}
109
110impl<I> SystemParamsReader<I>
111where
112    I: Borrow<PbSystemParams>,
113{
114    pub fn new(inner: I) -> Self {
115        Self { inner }
116    }
117
118    /// Return a new reader with the reference to the inner system params.
119    pub fn as_ref(&self) -> SystemParamsReader<&PbSystemParams> {
120        SystemParamsReader {
121            inner: self.inner(),
122        }
123    }
124
125    fn inner(&self) -> &PbSystemParams {
126        self.inner.borrow()
127    }
128}
129
130/// - Unwrap the field if it always exists.
131///   For example, if a parameter is introduced before the initial public release.
132///
133/// - Otherwise, specify the fallback logic when the field is missing.
134impl<I> SystemParamsRead for SystemParamsReader<I>
135where
136    I: Borrow<PbSystemParams>,
137{
138    fn barrier_interval_ms(&self) -> u32 {
139        self.inner().barrier_interval_ms.unwrap()
140    }
141
142    fn enforce_secret(&self) -> bool {
143        self.inner()
144            .enforce_secret
145            .unwrap_or_else(default::enforce_secret)
146    }
147
148    fn checkpoint_frequency(&self) -> u64 {
149        self.inner().checkpoint_frequency.unwrap()
150    }
151
152    fn parallel_compact_size_mb(&self) -> u32 {
153        self.inner().parallel_compact_size_mb.unwrap()
154    }
155
156    fn sstable_size_mb(&self) -> u32 {
157        self.inner().sstable_size_mb.unwrap()
158    }
159
160    fn block_size_kb(&self) -> u32 {
161        self.inner().block_size_kb.unwrap()
162    }
163
164    fn bloom_false_positive(&self) -> f64 {
165        self.inner().bloom_false_positive.unwrap()
166    }
167
168    fn state_store(&self) -> &str {
169        self.inner().state_store.as_ref().unwrap()
170    }
171
172    fn data_directory(&self) -> &str {
173        self.inner().data_directory.as_ref().unwrap()
174    }
175
176    fn use_new_object_prefix_strategy(&self) -> bool {
177        *self
178            .inner()
179            .use_new_object_prefix_strategy
180            .as_ref()
181            .unwrap()
182    }
183
184    fn backup_storage_url(&self) -> &str {
185        self.inner().backup_storage_url.as_ref().unwrap()
186    }
187
188    fn backup_storage_directory(&self) -> &str {
189        self.inner().backup_storage_directory.as_ref().unwrap()
190    }
191
192    fn max_concurrent_creating_streaming_jobs(&self) -> u32 {
193        self.inner().max_concurrent_creating_streaming_jobs.unwrap()
194    }
195
196    fn pause_on_next_bootstrap(&self) -> bool {
197        self.inner()
198            .pause_on_next_bootstrap
199            .unwrap_or_else(default::pause_on_next_bootstrap)
200    }
201
202    fn enable_tracing(&self) -> bool {
203        self.inner()
204            .enable_tracing
205            .unwrap_or_else(default::enable_tracing)
206    }
207
208    fn license_key(&self) -> LicenseKeyRef<'_> {
209        self.inner()
210            .license_key
211            .as_deref()
212            .unwrap_or_default()
213            .into()
214    }
215
216    fn time_travel_retention_ms(&self) -> u64 {
217        self.inner()
218            .time_travel_retention_ms
219            .unwrap_or_else(default::time_travel_retention_ms)
220    }
221
222    fn per_database_isolation(&self) -> <bool as ParamValue>::Borrowed<'_> {
223        self.inner()
224            .per_database_isolation
225            .unwrap_or_else(default::per_database_isolation)
226    }
227}