diff options
Diffstat (limited to 'examples/put_get.rs')
| -rw-r--r-- | examples/put_get.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/examples/put_get.rs b/examples/put_get.rs new file mode 100644 index 0000000..e2bfaca --- /dev/null +++ b/examples/put_get.rs @@ -0,0 +1,93 @@ +//! DHT put/get example (equivalent to example3.cpp). +//! +//! Creates a small network, stores key-value pairs from +//! one node, and retrieves them from another. +//! +//! Usage: +//! cargo run --example put_get + +use std::time::Duration; +use tesseras_dht::Node; +use tesseras_dht::nat::NatState; + +const NUM_NODES: usize = 5; + +fn main() { + env_logger::Builder::from_env( + env_logger::Env::default().default_filter_or("info"), + ) + .format(|buf, record| { + use std::io::Write; + writeln!( + buf, + "{} [{}] {}", + record.level(), + record.target(), + record.args() + ) + }) + .init(); + + // Create network + let mut nodes: Vec<Node> = Vec::new(); + let bootstrap = Node::bind(0).expect("bind"); + let bp = bootstrap.local_addr().unwrap().port(); + nodes.push(bootstrap); + nodes[0].set_nat_state(NatState::Global); + + for _ in 1..NUM_NODES { + let mut n = Node::bind(0).expect("bind"); + n.set_nat_state(NatState::Global); + n.join("127.0.0.1", bp).expect("join"); + nodes.push(n); + } + + // Poll to establish routing + for _ in 0..20 { + for n in nodes.iter_mut() { + n.poll().ok(); + } + std::thread::sleep(Duration::from_millis(50)); + } + + println!("Network ready: {NUM_NODES} nodes"); + + // Node 0 stores several key-value pairs + println!("\n--- Storing values from Node 0 ---"); + for i in 0..5u32 { + let key = format!("key-{i}"); + let val = format!("value-{i}"); + nodes[0].put(key.as_bytes(), val.as_bytes(), 300, false); + println!(" put({key}, {val})"); + } + + // Poll to distribute stores + for _ in 0..20 { + for n in nodes.iter_mut() { + n.poll().ok(); + } + std::thread::sleep(Duration::from_millis(50)); + } + + // Each node retrieves values + println!("\n--- Retrieving values ---"); + for (ni, node) in nodes.iter_mut().enumerate() { + for i in 0..5u32 { + let key = format!("key-{i}"); + let vals = node.get(key.as_bytes()); + let found: Vec<String> = vals + .iter() + .map(|v| String::from_utf8_lossy(v).to_string()) + .collect(); + if !found.is_empty() { + println!(" Node {ni} get({key}) = {:?}", found); + } + } + } + + // Summary + println!("\n--- Storage summary ---"); + for (i, n) in nodes.iter().enumerate() { + println!(" Node {i}: {} values stored", n.storage_count()); + } +} |