Skip to content

Commit 2fce027

Browse files
Using Arc<str> for the NodeId. (#186)
Co-authored-by: Paul Masurel <paul.masurel@datadoghq.com>
1 parent 7fe2a6f commit 2fce027

10 files changed

Lines changed: 55 additions & 38 deletions

File tree

LICENSE-3rdparty.csv

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ bytes,https://github.com/tokio-rs/bytes,MIT,"Carl Lerche <me@carllerche.com>, Se
77
cfg-if,https://github.com/rust-lang/cfg-if,MIT OR Apache-2.0,Alex Crichton <alex@alexcrichton.com>
88
chacha20,https://github.com/RustCrypto/stream-ciphers,MIT OR Apache-2.0,RustCrypto Developers
99
cpufeatures,https://github.com/RustCrypto/utils,MIT OR Apache-2.0,RustCrypto Developers
10-
either,https://github.com/rayon-rs/either,MIT OR Apache-2.0,bluss
10+
either,https://github.com/rayon-rs/either,MIT OR Apache-2.0,The either Authors
1111
equivalent,https://github.com/indexmap-rs/equivalent,Apache-2.0 OR MIT,The equivalent Authors
1212
foldhash,https://github.com/orlp/foldhash,Zlib,Orson Peters <orsonpeters@gmail.com>
1313
futures-core,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures-core Authors
1414
futures-sink,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures-sink Authors
1515
getrandom,https://github.com/rust-random/getrandom,MIT OR Apache-2.0,The Rand Project Developers
1616
hashbrown,https://github.com/rust-lang/hashbrown,MIT OR Apache-2.0,Amanieu d'Antras <amanieu@gmail.com>
17+
hashbrown,https://github.com/rust-lang/hashbrown,MIT OR Apache-2.0,The hashbrown Authors
1718
heck,https://github.com/withoutboats/heck,MIT OR Apache-2.0,The heck Authors
1819
id-arena,https://github.com/fitzgen/id-arena,MIT OR Apache-2.0,"Nick Fitzgerald <fitzgen@gmail.com>, Aleksey Kladov <aleksey.kladov@gmail.com>"
1920
indexmap,https://github.com/indexmap-rs/indexmap,Apache-2.0 OR MIT,The indexmap Authors

chitchat-test/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ rust-version = "1.86"
77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88

99
[dependencies]
10-
chitchat = { version = "0.10.1", path = "../chitchat" }
10+
chitchat = { version = "0.11.0", path = "../chitchat" }
1111
poem = "3.1.11"
1212
poem-openapi = {version="5.1.15", features = ["swagger-ui"] }
1313
structopt = "0.3"

chitchat/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "chitchat"
3-
version = "0.10.1"
3+
version = "0.11.0"
44
edition = "2024"
55
license = "MIT"
66
authors = ["Quickwit, Inc. <hello@quickwit.io>"]
@@ -17,7 +17,7 @@ bytes = "1"
1717
itertools = "0.14"
1818
lru = "0.17"
1919
rand = "0.10"
20-
serde = { version = "1", features = ["derive"] }
20+
serde = { version = "1", features = ["derive", "rc"] }
2121
tokio = { version = "1.28.0", features = [
2222
"net",
2323
"sync",

chitchat/src/failure_detector.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ mod tests {
361361

362362
let mut live_nodes = failure_detector
363363
.live_nodes()
364-
.map(|chitchat_id| chitchat_id.node_id.as_str())
364+
.map(|chitchat_id| &*chitchat_id.node_id)
365365
.collect::<Vec<_>>();
366366
live_nodes.sort_unstable();
367367
assert_eq!(live_nodes, vec!["node-10001", "node-10002", "node-10003"]);
@@ -374,7 +374,7 @@ mod tests {
374374
}
375375
let mut dead_nodes = failure_detector
376376
.dead_nodes()
377-
.map(|chitchat_id| chitchat_id.node_id.as_str())
377+
.map(|chitchat_id| &*chitchat_id.node_id)
378378
.collect::<Vec<_>>();
379379
dead_nodes.sort_unstable();
380380
assert_eq!(dead_nodes, vec!["node-10001", "node-10002", "node-10003"]);
@@ -386,20 +386,20 @@ mod tests {
386386
assert_eq!(
387387
failure_detector
388388
.live_nodes()
389-
.map(|chitchat_id| chitchat_id.node_id.as_str())
389+
.map(|chitchat_id| &*chitchat_id.node_id)
390390
.collect::<Vec<_>>(),
391391
Vec::<&str>::new()
392392
);
393393
assert_eq!(
394394
failure_detector
395395
.dead_nodes()
396-
.map(|chitchat_id| chitchat_id.node_id.as_str())
396+
.map(|chitchat_id| &*chitchat_id.node_id)
397397
.collect::<Vec<_>>(),
398398
Vec::<&str>::new()
399399
);
400400
let mut removed_nodes = garbage_collected_nodes
401401
.iter()
402-
.map(|chitchat_id| chitchat_id.node_id.as_str())
402+
.map(|chitchat_id| &*chitchat_id.node_id)
403403
.collect::<Vec<_>>();
404404
removed_nodes.sort_unstable();
405405
assert_eq!(
@@ -426,7 +426,7 @@ mod tests {
426426
assert_eq!(
427427
failure_detector
428428
.live_nodes()
429-
.map(|chitchat_id| chitchat_id.node_id.as_str())
429+
.map(|chitchat_id| &*chitchat_id.node_id)
430430
.collect::<Vec<_>>(),
431431
vec!["node-10001"]
432432
);
@@ -437,7 +437,7 @@ mod tests {
437437
assert_eq!(
438438
failure_detector
439439
.live_nodes()
440-
.map(|chitchat_id| chitchat_id.node_id.as_str())
440+
.map(|chitchat_id| &*chitchat_id.node_id)
441441
.collect::<Vec<_>>(),
442442
Vec::<&str>::new()
443443
);
@@ -452,7 +452,7 @@ mod tests {
452452
assert_eq!(
453453
failure_detector
454454
.live_nodes()
455-
.map(|chitchat_id| chitchat_id.node_id.as_str())
455+
.map(|chitchat_id| &*chitchat_id.node_id)
456456
.collect::<Vec<_>>(),
457457
vec!["node-10001"]
458458
);
@@ -479,7 +479,7 @@ mod tests {
479479

480480
let live_nodes = failure_detector
481481
.live_nodes()
482-
.map(|chitchat_id| chitchat_id.node_id.as_str())
482+
.map(|chitchat_id| &*chitchat_id.node_id)
483483
.collect::<Vec<_>>();
484484
assert_eq!(live_nodes, vec!["node-10001"]);
485485

@@ -488,7 +488,7 @@ mod tests {
488488

489489
let live_nodes = failure_detector
490490
.live_nodes()
491-
.map(|chitchat_id| chitchat_id.node_id.as_str())
491+
.map(|chitchat_id| &*chitchat_id.node_id)
492492
.collect::<Vec<_>>();
493493
assert_eq!(live_nodes, Vec::<&str>::new());
494494
}

chitchat/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ mod tests {
963963

964964
// Restart node at localhost:40001 with new name
965965
let mut new_config = ChitchatConfig::for_test(40_001);
966-
new_config.chitchat_id.node_id = "new_node".to_string();
966+
new_config.chitchat_id.node_id = Arc::from("new_node");
967967
let new_chitchat_id = new_config.chitchat_id.clone();
968968
let seed_addr = ChitchatId::for_local_test(40_002).gossip_advertise_addr;
969969
new_config.seed_nodes = vec![seed_addr.to_string()];
@@ -1354,7 +1354,7 @@ mod tests {
13541354

13551355
fn id(i: usize) -> ChitchatId {
13561356
ChitchatId {
1357-
node_id: "a".to_string().repeat(1000),
1357+
node_id: Arc::from("a".repeat(1000).as_str()),
13581358
generation_id: i as u64,
13591359
gossip_advertise_addr: SocketAddr::from(([127, 0, 0, 1], 10000u16 + i as u16)),
13601360
}

chitchat/src/serialize.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::io::BufRead;
22
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
3+
use std::sync::Arc;
34

45
use anyhow::{Context, bail};
56
use bytes::Buf;
@@ -183,18 +184,28 @@ impl Serializable for String {
183184
}
184185
}
185186

187+
fn deserialize_str<'a>(buf: &mut &'a [u8]) -> anyhow::Result<&'a str> {
188+
let len: usize = u16::deserialize(buf)? as usize;
189+
let str_bytes = buf.get(..len).with_context(|| {
190+
format!(
191+
"failed to deserialize string, buffer too short (str_len={len}, buf_len={})",
192+
buf.len()
193+
)
194+
})?;
195+
let s = std::str::from_utf8(str_bytes)?;
196+
buf.consume(len);
197+
Ok(s)
198+
}
199+
186200
impl Deserializable for String {
187201
fn deserialize(buf: &mut &[u8]) -> anyhow::Result<Self> {
188-
let len: usize = u16::deserialize(buf)? as usize;
189-
let str_bytes = buf.get(..len).with_context(|| {
190-
format!(
191-
"failed to deserialize string, buffer too short (str_len={len}, buf_len={})",
192-
buf.len()
193-
)
194-
})?;
195-
let str = std::str::from_utf8(str_bytes)?.to_string();
196-
buf.consume(len);
197-
Ok(str)
202+
Ok(deserialize_str(buf)?.to_owned())
203+
}
204+
}
205+
206+
impl Deserializable for Arc<str> {
207+
fn deserialize(buf: &mut &[u8]) -> anyhow::Result<Self> {
208+
Ok(Arc::from(deserialize_str(buf)?))
198209
}
199210
}
200211

@@ -264,7 +275,7 @@ impl Serializable for ChitchatId {
264275

265276
impl Deserializable for ChitchatId {
266277
fn deserialize(buf: &mut &[u8]) -> anyhow::Result<Self> {
267-
let node_id = String::deserialize(buf)?;
278+
let node_id: Arc<str> = Arc::<str>::deserialize(buf)?;
268279
let generation_id = u64::deserialize(buf)?;
269280
let gossip_advertise_addr = SocketAddr::deserialize(buf)?;
270281
Ok(Self {

chitchat/src/state.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::collections::{BTreeMap, HashSet};
44
use std::fmt::{Debug, Formatter};
55
use std::net::{Ipv4Addr, SocketAddr};
66
use std::ops::Bound;
7+
use std::sync::Arc;
78
use std::time::Duration;
89

910
use itertools::Itertools;
@@ -97,7 +98,7 @@ impl NodeState {
9798
pub fn for_test() -> NodeState {
9899
NodeState {
99100
chitchat_id: ChitchatId {
100-
node_id: "test-node".to_string(),
101+
node_id: Arc::from("test-node"),
101102
generation_id: 0,
102103
gossip_advertise_addr: SocketAddr::new(Ipv4Addr::new(127, 0, 0, 1).into(), 7280),
103104
},

chitchat/src/types.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::fmt::Debug;
22
use std::net::SocketAddr;
3+
use std::sync::Arc;
34

45
use serde::{Deserialize, Serialize};
56
use tokio::time::Instant;
@@ -20,7 +21,7 @@ use crate::serialize::Deserializable;
2021
#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
2122
pub struct ChitchatId {
2223
/// An identifier unique across the cluster.
23-
pub node_id: String,
24+
pub node_id: Arc<str>,
2425
/// A numeric identifier incremented every time the node leaves and rejoins the cluster.
2526
pub generation_id: u64,
2627
/// The socket address peers should use to gossip with the node.
@@ -32,17 +33,19 @@ impl Debug for ChitchatId {
3233
write!(
3334
f,
3435
"{}:{}:{}",
35-
self.node_id.as_str(),
36-
self.generation_id,
37-
self.gossip_advertise_addr
36+
&*self.node_id, self.generation_id, self.gossip_advertise_addr
3837
)
3938
}
4039
}
4140

4241
impl ChitchatId {
43-
pub fn new(node_id: String, generation_id: u64, gossip_advertise_addr: SocketAddr) -> Self {
42+
pub fn new(
43+
node_id: impl Into<Arc<str>>,
44+
generation_id: u64,
45+
gossip_advertise_addr: SocketAddr,
46+
) -> Self {
4447
Self {
45-
node_id,
48+
node_id: node_id.into(),
4649
generation_id,
4750
gossip_advertise_addr,
4851
}

chitchat/tests/cluster_test.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::{HashMap, HashSet};
22
use std::net::{SocketAddr, TcpListener};
3-
use std::sync::{Mutex, OnceLock};
3+
use std::sync::{Arc, Mutex, OnceLock};
44
use std::time::Duration;
55

66
use anyhow::anyhow;
@@ -445,15 +445,15 @@ impl Simulator {
445445
pub fn create_chitchat_id(id: &str) -> ChitchatId {
446446
let port = find_available_tcp_port().unwrap();
447447
ChitchatId {
448-
node_id: id.to_string(),
448+
node_id: Arc::from(id),
449449
generation_id: 0,
450450
gossip_advertise_addr: ([127, 0, 0, 1], port).into(),
451451
}
452452
}
453453

454454
pub fn test_chitchat_id(port: u16) -> ChitchatId {
455455
ChitchatId {
456-
node_id: format!("node_{port}"),
456+
node_id: Arc::from(format!("node_{port}").as_str()),
457457
generation_id: 0,
458458
gossip_advertise_addr: ([127, 0, 0, 1], port).into(),
459459
}

chitchat/tests/perf_test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::collections::BTreeMap;
22
use std::net::SocketAddr;
3+
use std::sync::Arc;
34
use std::time::Duration;
45

56
use chitchat::transport::{ChannelTransport, Transport, TransportExt};
@@ -13,7 +14,7 @@ use tracing::info;
1314
async fn spawn_one(chitchat_id: u16, transport: &dyn Transport) -> ChitchatHandle {
1415
let listen_addr: SocketAddr = ([127, 0, 0, 1], 10_000u16 + chitchat_id).into();
1516
let chitchat_id = ChitchatId {
16-
node_id: format!("node_{chitchat_id}"),
17+
node_id: Arc::from(format!("node_{chitchat_id}").as_str()),
1718
generation_id: 0,
1819
gossip_advertise_addr: listen_addr,
1920
};

0 commit comments

Comments
 (0)