TLA Line data Source code
1 : use std::{fmt, str::FromStr};
2 :
3 : use anyhow::Context;
4 : use hex::FromHex;
5 : use rand::Rng;
6 : use serde::de::Visitor;
7 : use serde::{Deserialize, Serialize};
8 : use thiserror::Error;
9 :
10 UBC 0 : #[derive(Error, Debug)]
11 : pub enum IdError {
12 : #[error("invalid id length {0}")]
13 : SliceParseError(usize),
14 : }
15 :
16 : /// Neon ID is a 128-bit random ID.
17 : /// Used to represent various identifiers. Provides handy utility methods and impls.
18 : ///
19 : /// NOTE: It (de)serializes as an array of hex bytes, so the string representation would look
20 : /// like `[173,80,132,115,129,226,72,254,170,201,135,108,199,26,228,24]`.
21 CBC 22218655 : #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
22 : struct Id([u8; 16]);
23 :
24 : impl Serialize for Id {
25 62268 : fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
26 62268 : where
27 62268 : S: serde::Serializer,
28 62268 : {
29 62268 : if serializer.is_human_readable() {
30 15489 : serializer.collect_str(self)
31 : } else {
32 46779 : self.0.serialize(serializer)
33 : }
34 62268 : }
35 : }
36 :
37 : impl<'de> Deserialize<'de> for Id {
38 107030 : fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
39 107030 : where
40 107030 : D: serde::Deserializer<'de>,
41 107030 : {
42 107030 : struct IdVisitor {
43 107030 : is_human_readable_deserializer: bool,
44 107030 : }
45 107030 :
46 107030 : impl<'de> Visitor<'de> for IdVisitor {
47 107030 : type Value = Id;
48 107030 :
49 107030 : fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
50 UBC 0 : if self.is_human_readable_deserializer {
51 CBC 107030 : formatter.write_str("value in form of hex string")
52 107030 : } else {
53 107030 : formatter.write_str("value in form of integer array([u8; 16])")
54 107030 : }
55 107030 : }
56 107030 :
57 107030 : fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
58 70127 : where
59 70127 : A: serde::de::SeqAccess<'de>,
60 70127 : {
61 70127 : let s = serde::de::value::SeqAccessDeserializer::new(seq);
62 107030 : let id: [u8; 16] = Deserialize::deserialize(s)?;
63 107030 : Ok(Id::from(id))
64 107030 : }
65 107030 :
66 107030 : fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
67 36903 : where
68 36903 : E: serde::de::Error,
69 36903 : {
70 36903 : Id::from_str(v).map_err(E::custom)
71 36903 : }
72 107030 : }
73 107030 :
74 107030 : if deserializer.is_human_readable() {
75 36903 : deserializer.deserialize_str(IdVisitor {
76 36903 : is_human_readable_deserializer: true,
77 36903 : })
78 : } else {
79 70127 : deserializer.deserialize_tuple(
80 70127 : 16,
81 70127 : IdVisitor {
82 70127 : is_human_readable_deserializer: false,
83 70127 : },
84 70127 : )
85 : }
86 107030 : }
87 : }
88 :
89 : impl Id {
90 UBC 0 : pub fn get_from_buf(buf: &mut impl bytes::Buf) -> Id {
91 0 : let mut arr = [0u8; 16];
92 0 : buf.copy_to_slice(&mut arr);
93 0 : Id::from(arr)
94 0 : }
95 :
96 CBC 43830 : pub fn from_slice(src: &[u8]) -> Result<Id, IdError> {
97 43830 : if src.len() != 16 {
98 UBC 0 : return Err(IdError::SliceParseError(src.len()));
99 CBC 43830 : }
100 43830 : let mut id_array = [0u8; 16];
101 43830 : id_array.copy_from_slice(src);
102 43830 : Ok(id_array.into())
103 43830 : }
104 :
105 9 : pub fn as_arr(&self) -> [u8; 16] {
106 9 : self.0
107 9 : }
108 :
109 925 : pub fn generate() -> Self {
110 925 : let mut tli_buf = [0u8; 16];
111 925 : rand::thread_rng().fill(&mut tli_buf);
112 925 : Id::from(tli_buf)
113 925 : }
114 :
115 4318154 : fn hex_encode(&self) -> String {
116 4318154 : static HEX: &[u8] = b"0123456789abcdef";
117 4318154 :
118 4318154 : let mut buf = vec![0u8; self.0.len() * 2];
119 69090464 : for (&b, chunk) in self.0.as_ref().iter().zip(buf.chunks_exact_mut(2)) {
120 69090464 : chunk[0] = HEX[((b >> 4) & 0xf) as usize];
121 69090464 : chunk[1] = HEX[(b & 0xf) as usize];
122 69090464 : }
123 :
124 : // SAFETY: vec constructed out of `HEX`, it can only be ascii
125 4318154 : unsafe { String::from_utf8_unchecked(buf) }
126 4318154 : }
127 : }
128 :
129 : impl FromStr for Id {
130 : type Err = hex::FromHexError;
131 :
132 80130 : fn from_str(s: &str) -> Result<Id, Self::Err> {
133 80130 : Self::from_hex(s)
134 80130 : }
135 : }
136 :
137 : // this is needed for pretty serialization and deserialization of Id's using serde integration with hex crate
138 : impl FromHex for Id {
139 : type Error = hex::FromHexError;
140 :
141 80511 : fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
142 80511 : let mut buf: [u8; 16] = [0u8; 16];
143 80511 : hex::decode_to_slice(hex, &mut buf)?;
144 79055 : Ok(Id(buf))
145 80511 : }
146 : }
147 :
148 : impl AsRef<[u8]> for Id {
149 UBC 0 : fn as_ref(&self) -> &[u8] {
150 0 : &self.0
151 0 : }
152 : }
153 :
154 : impl From<[u8; 16]> for Id {
155 CBC 128561 : fn from(b: [u8; 16]) -> Self {
156 128561 : Id(b)
157 128561 : }
158 : }
159 :
160 : impl From<Id> for u128 {
161 263 : fn from(id: Id) -> Self {
162 263 : u128::from_le_bytes(id.0)
163 263 : }
164 : }
165 :
166 : impl fmt::Display for Id {
167 4312455 : fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168 4312455 : f.write_str(&self.hex_encode())
169 4312455 : }
170 : }
171 :
172 : impl fmt::Debug for Id {
173 5699 : fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 5699 : f.write_str(&self.hex_encode())
175 5699 : }
176 : }
177 :
178 : macro_rules! id_newtype {
179 : ($t:ident) => {
180 : impl $t {
181 UBC 0 : pub fn get_from_buf(buf: &mut impl bytes::Buf) -> $t {
182 0 : $t(Id::get_from_buf(buf))
183 0 : }
184 :
185 CBC 43830 : pub fn from_slice(src: &[u8]) -> Result<$t, IdError> {
186 43830 : Ok($t(Id::from_slice(src)?))
187 43830 : }
188 :
189 9 : pub fn as_arr(&self) -> [u8; 16] {
190 9 : self.0.as_arr()
191 9 : }
192 :
193 925 : pub fn generate() -> Self {
194 925 : $t(Id::generate())
195 925 : }
196 :
197 4 : pub const fn from_array(b: [u8; 16]) -> Self {
198 4 : $t(Id(b))
199 4 : }
200 : }
201 :
202 : impl FromStr for $t {
203 : type Err = hex::FromHexError;
204 :
205 43227 : fn from_str(s: &str) -> Result<$t, Self::Err> {
206 43227 : let value = Id::from_str(s)?;
207 41771 : Ok($t(value))
208 43227 : }
209 : }
210 :
211 : impl From<[u8; 16]> for $t {
212 13678 : fn from(b: [u8; 16]) -> Self {
213 13678 : $t(Id::from(b))
214 13678 : }
215 : }
216 :
217 : impl FromHex for $t {
218 : type Error = hex::FromHexError;
219 :
220 381 : fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
221 381 : Ok($t(Id::from_hex(hex)?))
222 381 : }
223 : }
224 :
225 : impl AsRef<[u8]> for $t {
226 30832 : fn as_ref(&self) -> &[u8] {
227 30832 : &self.0 .0
228 30832 : }
229 : }
230 :
231 : impl From<$t> for u128 {
232 263 : fn from(id: $t) -> Self {
233 263 : u128::from(id.0)
234 263 : }
235 : }
236 :
237 : impl fmt::Display for $t {
238 4296966 : fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
239 4296966 : self.0.fmt(f)
240 4296966 : }
241 : }
242 :
243 : impl fmt::Debug for $t {
244 5699 : fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245 5699 : self.0.fmt(f)
246 5699 : }
247 : }
248 : };
249 : }
250 :
251 : /// Neon timeline IDs are different from PostgreSQL timeline
252 : /// IDs. They serve a similar purpose though: they differentiate
253 : /// between different "histories" of the same cluster. However,
254 : /// PostgreSQL timeline IDs are a bit cumbersome, because they are only
255 : /// 32-bits wide, and they must be in ascending order in any given
256 : /// timeline history. Those limitations mean that we cannot generate a
257 : /// new PostgreSQL timeline ID by just generating a random number. And
258 : /// that in turn is problematic for the "pull/push" workflow, where you
259 : /// have a local copy of a Neon repository, and you periodically sync
260 : /// the local changes with a remote server. When you work "detached"
261 : /// from the remote server, you cannot create a PostgreSQL timeline ID
262 : /// that's guaranteed to be different from all existing timelines in
263 : /// the remote server. For example, if two people are having a clone of
264 : /// the repository on their laptops, and they both create a new branch
265 : /// with different name. What timeline ID would they assign to their
266 : /// branches? If they pick the same one, and later try to push the
267 : /// branches to the same remote server, they will get mixed up.
268 : ///
269 : /// To avoid those issues, Neon has its own concept of timelines that
270 : /// is separate from PostgreSQL timelines, and doesn't have those
271 : /// limitations. A Neon timeline is identified by a 128-bit ID, which
272 : /// is usually printed out as a hex string.
273 : ///
274 : /// NOTE: It (de)serializes as an array of hex bytes, so the string representation would look
275 : /// like `[173,80,132,115,129,226,72,254,170,201,135,108,199,26,228,24]`.
276 : /// See [`Id`] for alternative ways to serialize it.
277 12062376 : #[derive(Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
278 : pub struct TimelineId(Id);
279 :
280 : id_newtype!(TimelineId);
281 :
282 : impl TryFrom<Option<&str>> for TimelineId {
283 : type Error = anyhow::Error;
284 :
285 374 : fn try_from(value: Option<&str>) -> Result<Self, Self::Error> {
286 374 : value
287 374 : .unwrap_or_default()
288 374 : .parse::<TimelineId>()
289 374 : .with_context(|| format!("Could not parse timeline id from {:?}", value))
290 374 : }
291 : }
292 :
293 : /// Neon Tenant Id represents identifiar of a particular tenant.
294 : /// Is used for distinguishing requests and data belonging to different users.
295 : ///
296 : /// NOTE: It (de)serializes as an array of hex bytes, so the string representation would look
297 : /// like `[173,80,132,115,129,226,72,254,170,201,135,108,199,26,228,24]`.
298 : /// See [`Id`] for alternative ways to serialize it.
299 11099560 : #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
300 : pub struct TenantId(Id);
301 :
302 : id_newtype!(TenantId);
303 :
304 : /// Neon Connection Id identifies long-lived connections (for example a pagestream
305 : /// connection with the page_service). Is used for better logging and tracing
306 : ///
307 : /// NOTE: It (de)serializes as an array of hex bytes, so the string representation would look
308 : /// like `[173,80,132,115,129,226,72,254,170,201,135,108,199,26,228,24]`.
309 : /// See [`Id`] for alternative ways to serialize it.
310 UBC 0 : #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
311 : pub struct ConnectionId(Id);
312 :
313 : id_newtype!(ConnectionId);
314 :
315 : // A pair uniquely identifying Neon instance.
316 CBC 28358 : #[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)]
317 : pub struct TenantTimelineId {
318 : pub tenant_id: TenantId,
319 : pub timeline_id: TimelineId,
320 : }
321 :
322 : impl TenantTimelineId {
323 10662 : pub fn new(tenant_id: TenantId, timeline_id: TimelineId) -> Self {
324 10662 : TenantTimelineId {
325 10662 : tenant_id,
326 10662 : timeline_id,
327 10662 : }
328 10662 : }
329 :
330 2 : pub fn generate() -> Self {
331 2 : Self::new(TenantId::generate(), TimelineId::generate())
332 2 : }
333 :
334 3127 : pub fn empty() -> Self {
335 3127 : Self::new(TenantId::from([0u8; 16]), TimelineId::from([0u8; 16]))
336 3127 : }
337 : }
338 :
339 : impl fmt::Display for TenantTimelineId {
340 9239 : fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
341 9239 : write!(f, "{}/{}", self.tenant_id, self.timeline_id)
342 9239 : }
343 : }
344 :
345 : impl FromStr for TenantTimelineId {
346 : type Err = anyhow::Error;
347 :
348 UBC 0 : fn from_str(s: &str) -> Result<Self, Self::Err> {
349 0 : let mut parts = s.split('/');
350 0 : let tenant_id = parts
351 0 : .next()
352 0 : .ok_or_else(|| anyhow::anyhow!("TenantTimelineId must contain tenant_id"))?
353 0 : .parse()?;
354 0 : let timeline_id = parts
355 0 : .next()
356 0 : .ok_or_else(|| anyhow::anyhow!("TenantTimelineId must contain timeline_id"))?
357 0 : .parse()?;
358 0 : if parts.next().is_some() {
359 0 : anyhow::bail!("TenantTimelineId must contain only tenant_id and timeline_id");
360 0 : }
361 0 : Ok(TenantTimelineId::new(tenant_id, timeline_id))
362 0 : }
363 : }
364 :
365 : // Unique ID of a storage node (safekeeper or pageserver). Supposed to be issued
366 : // by the console.
367 CBC 1067681 : #[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Hash, Debug, Serialize, Deserialize)]
368 : #[serde(transparent)]
369 : pub struct NodeId(pub u64);
370 :
371 : impl fmt::Display for NodeId {
372 16902 : fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
373 16902 : write!(f, "{}", self.0)
374 16902 : }
375 : }
376 :
377 : #[cfg(test)]
378 : mod tests {
379 : use serde_assert::{Deserializer, Serializer, Token, Tokens};
380 :
381 : use crate::bin_ser::BeSer;
382 :
383 : use super::*;
384 :
385 1 : #[test]
386 1 : fn test_id_serde_non_human_readable() {
387 1 : let original_id = Id([
388 1 : 173, 80, 132, 115, 129, 226, 72, 254, 170, 201, 135, 108, 199, 26, 228, 24,
389 1 : ]);
390 1 : let expected_tokens = Tokens(vec![
391 1 : Token::Tuple { len: 16 },
392 1 : Token::U8(173),
393 1 : Token::U8(80),
394 1 : Token::U8(132),
395 1 : Token::U8(115),
396 1 : Token::U8(129),
397 1 : Token::U8(226),
398 1 : Token::U8(72),
399 1 : Token::U8(254),
400 1 : Token::U8(170),
401 1 : Token::U8(201),
402 1 : Token::U8(135),
403 1 : Token::U8(108),
404 1 : Token::U8(199),
405 1 : Token::U8(26),
406 1 : Token::U8(228),
407 1 : Token::U8(24),
408 1 : Token::TupleEnd,
409 1 : ]);
410 1 :
411 1 : let serializer = Serializer::builder().is_human_readable(false).build();
412 1 : let serialized_tokens = original_id.serialize(&serializer).unwrap();
413 1 : assert_eq!(serialized_tokens, expected_tokens);
414 :
415 1 : let mut deserializer = Deserializer::builder()
416 1 : .is_human_readable(false)
417 1 : .tokens(serialized_tokens)
418 1 : .build();
419 1 : let deserialized_id = Id::deserialize(&mut deserializer).unwrap();
420 1 : assert_eq!(deserialized_id, original_id);
421 1 : }
422 :
423 1 : #[test]
424 1 : fn test_id_serde_human_readable() {
425 1 : let original_id = Id([
426 1 : 173, 80, 132, 115, 129, 226, 72, 254, 170, 201, 135, 108, 199, 26, 228, 24,
427 1 : ]);
428 1 : let expected_tokens = Tokens(vec![Token::Str(String::from(
429 1 : "ad50847381e248feaac9876cc71ae418",
430 1 : ))]);
431 1 :
432 1 : let serializer = Serializer::builder().is_human_readable(true).build();
433 1 : let serialized_tokens = original_id.serialize(&serializer).unwrap();
434 1 : assert_eq!(serialized_tokens, expected_tokens);
435 :
436 1 : let mut deserializer = Deserializer::builder()
437 1 : .is_human_readable(true)
438 1 : .tokens(Tokens(vec![Token::Str(String::from(
439 1 : "ad50847381e248feaac9876cc71ae418",
440 1 : ))]))
441 1 : .build();
442 1 : assert_eq!(Id::deserialize(&mut deserializer).unwrap(), original_id);
443 1 : }
444 :
445 : macro_rules! roundtrip_type {
446 : ($type:ty, $expected_bytes:expr) => {{
447 : let expected_bytes: [u8; 16] = $expected_bytes;
448 : let original_id = <$type>::from(expected_bytes);
449 :
450 : let ser_bytes = original_id.ser().unwrap();
451 : assert_eq!(ser_bytes, expected_bytes);
452 :
453 : let des_id = <$type>::des(&ser_bytes).unwrap();
454 : assert_eq!(des_id, original_id);
455 : }};
456 : }
457 :
458 1 : #[test]
459 1 : fn test_id_bincode_serde() {
460 1 : let expected_bytes = [
461 1 : 173, 80, 132, 115, 129, 226, 72, 254, 170, 201, 135, 108, 199, 26, 228, 24,
462 1 : ];
463 1 :
464 1 : roundtrip_type!(Id, expected_bytes);
465 1 : }
466 :
467 1 : #[test]
468 1 : fn test_tenant_id_bincode_serde() {
469 1 : let expected_bytes = [
470 1 : 173, 80, 132, 115, 129, 226, 72, 254, 170, 201, 135, 108, 199, 26, 228, 24,
471 1 : ];
472 1 :
473 1 : roundtrip_type!(TenantId, expected_bytes);
474 1 : }
475 :
476 1 : #[test]
477 1 : fn test_timeline_id_bincode_serde() {
478 1 : let expected_bytes = [
479 1 : 173, 80, 132, 115, 129, 226, 72, 254, 170, 201, 135, 108, 199, 26, 228, 24,
480 1 : ];
481 1 :
482 1 : roundtrip_type!(TimelineId, expected_bytes);
483 1 : }
484 : }
|