aboutsummaryrefslogtreecommitdiffstats
path: root/examples/put_get.rs
blob: e2bfaca21cd2a243a6975a22e58b9cc4e27278ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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());
    }
}