Skip to main content

snowflake_distributed/
snowflake_distributed.rs

1//! Snowflake deep dive — distributed worker IDs and decomposition.
2//!
3//! Demonstrates:
4//!   * `Snowflake::new` for a single-host worker
5//!   * `Snowflake::with_epoch` for a custom epoch (e.g. the Twitter
6//!     2010 epoch)
7//!   * `Snowflake::parts` to decode any ID back into
8//!     `(timestamp_offset, worker, sequence)`
9//!   * Multi-threaded contention producing globally unique IDs
10//!
11//! Run with: `cargo run --release --example snowflake_distributed`
12
13use id_forge::snowflake::{Snowflake, DEFAULT_EPOCH_MS};
14use std::collections::HashSet;
15use std::sync::Arc;
16use std::thread;
17
18fn main() {
19    println!("== Default epoch (2026-01-01) ==");
20    let gen = Snowflake::new(7);
21    let id = gen.next_id();
22    let (ts_offset, worker, seq) = Snowflake::parts(id);
23    let wall_ms = ts_offset + gen.epoch_ms();
24    println!("id           = {id}");
25    println!("worker       = {worker}");
26    println!("seq          = {seq}");
27    println!("ts_offset_ms = {ts_offset}");
28    println!("wall_ms      = {wall_ms}");
29    println!("default epoch = {DEFAULT_EPOCH_MS}");
30
31    println!("\n== Twitter's original 2010 epoch ==");
32    let twitter_epoch_ms = 1_288_834_974_657;
33    let tw = Snowflake::with_epoch(9, twitter_epoch_ms);
34    let tw_id = tw.next_id();
35    let (tw_ts, tw_worker, _) = Snowflake::parts(tw_id);
36    println!("id           = {tw_id}");
37    println!("worker       = {tw_worker}");
38    println!("ts_offset_ms = {tw_ts}");
39    println!("wall_ms      = {}", tw_ts + tw.epoch_ms());
40
41    println!("\n== Multi-thread contention (8 threads x 2000 IDs) ==");
42    let gen = Arc::new(Snowflake::new(3));
43    let handles: Vec<_> = (0..8)
44        .map(|_| {
45            let g = Arc::clone(&gen);
46            thread::spawn(move || (0..2000).map(|_| g.next_id()).collect::<Vec<_>>())
47        })
48        .collect();
49
50    let mut all = HashSet::new();
51    for h in handles {
52        for id in h.join().unwrap() {
53            all.insert(id);
54        }
55    }
56    println!("expected     = {}", 8 * 2000);
57    println!("unique seen  = {}", all.len());
58    println!("no duplicates= {}", all.len() == 8 * 2000);
59
60    println!("\n== Worker ID clamping ==");
61    let clamped = Snowflake::new(0xFFFF);
62    println!(
63        "constructor input 0xFFFF -> worker_id() = {}",
64        clamped.worker_id()
65    );
66    println!("(10-bit max = {})", 0x3FF);
67}