diff --git a/gg-g_counter/src/main.rs b/gg-g_counter/src/main.rs index edc3498..6ee5d04 100644 --- a/gg-g_counter/src/main.rs +++ b/gg-g_counter/src/main.rs @@ -1,12 +1,13 @@ use nebkor_maelstrom::{kv::Kv, mk_payload, Body, Message, Node, Runner}; +use serde_json::Value; const KEY: &str = "COUNTER"; #[derive(Clone, Default)] -struct Counter(i64); +struct Counter; fn main() { - let node = Counter(0); + let node = Counter; let runner = Runner::new(node); @@ -20,14 +21,6 @@ fn main() { runner.run(Some(on_init)); } -fn gossip(neighbors: &[&String], runner: &Runner, val: i64) { - let payload = mk_payload(&[("goss", val.into())]); - let body = Body::from_type("gossip").with_payload(payload); - for node in neighbors { - runner.send(node, body.clone()); - } -} - impl Node for Counter { fn handle(&mut self, runner: &Runner, req: Message) { let typ = req.body.typ.as_str(); @@ -37,34 +30,26 @@ impl Node for Counter { let delta = req.body.payload.get("delta").unwrap().as_i64().unwrap(); loop { let cur = kv.read(runner, KEY).unwrap().unwrap().as_i64().unwrap(); - let cur = cur.max(self.0); let new = cur + delta; - match kv.cas(runner, KEY, cur.into(), new.into(), false) { - Err(_e) => {} - Ok(_) => { - let nodes = runner - .nodes() - .iter() - .filter(|e| e != &&runner.node_id()) - .collect::>(); - self.0 = new; - gossip(&nodes, runner, new); - break; - } + if kv.cas(runner, KEY, cur.into(), new.into(), false).is_ok() { + break; } } runner.reply(&req, Body::from_type("add_ok")); } "read" => { - let val = self.0; - let body = - Body::from_type("read_ok").with_payload(mk_payload(&[("value", val.into())])); - runner.reply(&req, body); - } + let mut rounds = 0; + let mut val = Value::Null; + while rounds < 2 { + let v = kv.read(runner, KEY).unwrap().unwrap(); + if kv.cas(runner, KEY, v.clone(), v.clone(), false).is_ok() { + rounds += 1; + } + val = v; + } - "gossip" => { - let val = req.body.payload.get("goss").unwrap().as_i64().unwrap(); - self.0 = val.max(self.0); + let body = Body::from_type("read_ok").with_payload(mk_payload(&[("value", val)])); + runner.reply(&req, body); } _ => { eprintln!("unknown type: {req:?}");