diff options
Diffstat (limited to 'unique_ids')
-rw-r--r-- | unique_ids/Cargo.toml | 12 | ||||
-rw-r--r-- | unique_ids/src/main.rs | 83 |
2 files changed, 95 insertions, 0 deletions
diff --git a/unique_ids/Cargo.toml b/unique_ids/Cargo.toml new file mode 100644 index 0000000..e7424bf --- /dev/null +++ b/unique_ids/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "unique_ids" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = { version = "1.0.185", features = ["derive"] } +serde_json = "1.0.105" +common = { path = "../common/" } +rand = "0.8.5" diff --git a/unique_ids/src/main.rs b/unique_ids/src/main.rs new file mode 100644 index 0000000..3787033 --- /dev/null +++ b/unique_ids/src/main.rs @@ -0,0 +1,83 @@ +use std::{ + io, + time::{SystemTime, UNIX_EPOCH}, +}; + +use common::{run_with, Handler}; +use rand::{rngs::StdRng, Rng, SeedableRng}; +use serde::{Deserialize, Serialize}; + +fn main() { + run_with::<UniqueIdsHandler>(io::stdin(), io::stdout()) +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(tag = "type")] +enum UniqueIdsBody { + #[serde(rename = "generate")] + Generate { msg_id: usize }, + + #[serde(rename = "generate_ok")] + GenerateOk { + msg_id: usize, + in_reply_to: usize, + id: u128, + }, +} + +type RngMethod = StdRng; + +struct UniqueIdsHandler { + rng: RngMethod, + next_msg_id: usize, +} + +impl Handler for UniqueIdsHandler { + type Body = UniqueIdsBody; + + fn init(_node_id: String, _node_ids: Vec<String>, _msg_id: usize) -> Self { + Self { + rng: RngMethod::from_entropy(), // TODO: This could be seeded from the node ID + next_msg_id: 1, + } + } + + fn handle( + &mut self, + header: common::msg::MessageHeader, + body: Self::Body, + writer: &mut common::MsgWriter<impl std::io::Write>, + ) -> () { + match body { + UniqueIdsBody::Generate { msg_id } => { + let id = self.gen_id(); + writer.write( + header.src, + &UniqueIdsBody::GenerateOk { + msg_id: self.next_msg_id, + in_reply_to: msg_id, + id, + }, + ); + + self.next_msg_id += 1; + } + UniqueIdsBody::GenerateOk { .. } => (), + }; + } +} + +impl UniqueIdsHandler { + fn gen_id(&mut self) -> u128 { + // Time since UNIX epoch in milliseconds + let now = SystemTime::now(); + let time_millis: u128 = now.duration_since(UNIX_EPOCH).unwrap().as_millis(); + + // 80 bits of randomness + let rand1: u16 = self.rng.gen(); + let rand2: u64 = self.rng.gen(); + let rand: u128 = rand1 as u128 | ((rand2 as u128) << 64); + + (time_millis << 80) | rand + } +} |