49 lines
1.4 KiB
Rust
49 lines
1.4 KiB
Rust
use nebkor_maelstrom::{kv::Kv, mk_payload, Body, Message, Node, Runner};
|
|
|
|
const KEY: &str = "COUNTER";
|
|
|
|
#[derive(Clone, Default)]
|
|
struct Counter;
|
|
|
|
fn main() {
|
|
let node = Counter;
|
|
|
|
let runner = Runner::new(node);
|
|
|
|
let on_init = |rnr: &Runner| {
|
|
let kv = Kv::seq();
|
|
let _ = kv.cas(rnr, KEY, 0i64.into(), 0i64.into(), true);
|
|
};
|
|
|
|
let on_init = Box::new(on_init);
|
|
|
|
runner.run(Some(on_init));
|
|
}
|
|
|
|
impl Node for Counter {
|
|
fn handle(&mut self, runner: &Runner, req: Message) {
|
|
let typ = req.body.typ.as_str();
|
|
let kv = Kv::seq();
|
|
match typ {
|
|
"add" => {
|
|
let delta = req.body.payload.get("delta").unwrap().as_i64().unwrap();
|
|
loop {
|
|
let cur = kv.read(runner, KEY).unwrap().unwrap().as_i64().unwrap();
|
|
match kv.cas(runner, KEY, cur.into(), (cur + delta).into(), false) {
|
|
Err(_) => {}
|
|
Ok(_) => break,
|
|
}
|
|
}
|
|
runner.reply(&req, Body::from_type("add_ok"));
|
|
}
|
|
"read" => {
|
|
let val = kv.read(runner, KEY).unwrap().unwrap();
|
|
let body = Body::from_type("read_ok").with_payload(mk_payload(&[("value", val)]));
|
|
runner.reply(&req, body);
|
|
}
|
|
_ => {
|
|
eprintln!("unknown type: {req:?}");
|
|
}
|
|
}
|
|
}
|
|
}
|