Skip to content

Commit

Permalink
feat: use atomic increment for kvcounter
Browse files Browse the repository at this point in the history
Signed-off-by: Victor Adossi <[email protected]>
  • Loading branch information
vados-cosmonic authored and brooksmtownsend committed Sep 13, 2023
1 parent b609917 commit daf7fdd
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 80 deletions.
2 changes: 1 addition & 1 deletion actor/kvcounter-wasmcon2023/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ wash start actor file:///path/to/your/build/wasmcon2023_keyvalue_s.wasm --host <
Your output should look something like the following:

```
Actor [MD3T2JMVXPP2DNY3YGVIXOFHPSCOUQOE4IFOLC4EKDB3QFOTWQPHACAH] (ref: [file:///home/mrman/code/work/cosmonic/forks/examples/actor/kvcounter-wasmcon2023/build/wasmcon2023_keyvalue_s.wasm]) started on host [NAYIPQDLQE62R3XEICJZXJEOCUASMA5BC24O76H3ONVIJS7ONTNBWQYI]
Actor [MD3T2JMVXPP2DNY3YGVIXOFHPSCOUQOE4IFOLC4EKDB3QFOTWQPHACAH] (ref: [file:///path/to/examples/actor/kvcounter-wasmcon2023/build/wasmcon2023_keyvalue_s.wasm]) started on host [NAYIPQDLQE62R3XEICJZXJEOCUASMA5BC24O76H3ONVIJS7ONTNBWQYI]
```

Take a note of the Actor ID for your actor. For example it should look something like this:
Expand Down
111 changes: 32 additions & 79 deletions actor/kvcounter-wasmcon2023/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ wit_bindgen::generate!({
}
});

use anyhow::{anyhow, Context};
use anyhow::anyhow;
use http::StatusCode;
use serde::Serialize;
use wasi::{
Expand All @@ -15,12 +15,7 @@ use wasi::{
ResponseOutparam,
},
io::streams::write,
keyvalue::{
readwrite::{get, set},
types::{
incoming_value_consume_sync, new_outgoing_value, open_bucket, outgoing_value_write_body,
},
},
keyvalue::{atomic::increment, types::open_bucket},
};

mod ui;
Expand All @@ -34,49 +29,6 @@ const BUCKET: &str = "";
/// Implementation struct for the 'kvcounter' world (see: wit/kvcounter.wit)
struct KvCounter;

impl KvCounter {
/// Increment (possibly negatively) the counter for a given key
fn increment_counter(bucket: u32, key: &String, amount: i32) -> anyhow::Result<i32> {
let current_value: i32 = match get(bucket, key) {
// If the value exists, parse it into an i32
Ok(incoming_value) => {
// Read bytes from incoming value
let bytes = incoming_value_consume_sync(incoming_value)
.map_err(|count| anyhow!("failed to parse incoming bytes, read [{count}]"))?;
// Convert the bytes to a i32
String::from_utf8(bytes)
.context("failed to parse string from returned bytes")?
.trim()
.parse()
.context("failed to parse i32 from bytes")?
}
// If the value is missing or we fail to get it, assume it is zero
Err(_) => {
eprintln!("[warn] encountered missing key [{key}], defaulting to 0");
0
}
};

// Calculate the new value
let new_value: i32 = current_value + amount;

// Build outgoing value to use
let outgoing_value = new_outgoing_value();
let stream = outgoing_value_write_body(outgoing_value)
.map_err(|_| anyhow!("failed to write outgoing value"))?;

// Write out the new value
write(stream, new_value.to_string().as_bytes())
.map_err(|e| anyhow!("failed to write to outgoing value stream: {e}"))?;

// Set the key to the updated value
set(bucket, key, outgoing_value).map_err(|e| anyhow!("failed to set value: {e}"))?;

// Cheat and just assume the new value will be the increment
Ok(new_value)
}
}

/// Implementation of the WIT-driven incoming-handler interface for our implementation struct
impl Guest for KvCounter {
fn handle(request: IncomingRequest, response: ResponseOutparam) {
Expand Down Expand Up @@ -135,20 +87,20 @@ impl Guest for KvCounter {
};

// Increment the counter
let updated_value =
match KvCounter::increment_counter(bucket, &String::from("default"), 1) {
Ok(v) => v,
Err(_) => {
write_http_response(
response,
500,
&content_type_json(),
ApiResponse::error("failed to increment default counter")
.into_vec(),
);
return;
}
};
let updated_value = match increment(bucket, &String::from("default"), 1)
.map_err(|_| anyhow!("failed to increment value in bucket"))
{
Ok(v) => v,
Err(_) => {
write_http_response(
response,
500,
&content_type_json(),
ApiResponse::error("failed to increment default counter").into_vec(),
);
return;
}
};

// Build & write the response the response
eprintln!("[success] successfully incremented default counter");
Expand Down Expand Up @@ -178,19 +130,20 @@ impl Guest for KvCounter {
};

// Increment the counter
let updated_value =
match KvCounter::increment_counter(bucket, &counter.to_string(), 1) {
Ok(v) => v,
Err(e) => {
write_http_response(
response,
500,
&content_type_json(),
ApiResponse::error(format!("{e}")).into_vec(),
);
return;
}
};
let updated_value = match increment(bucket, &counter.to_string(), 1)
.map_err(|_| anyhow!("failed to increment value in bucket"))
{
Ok(v) => v,
Err(e) => {
write_http_response(
response,
500,
&content_type_json(),
ApiResponse::error(format!("{e}")).into_vec(),
);
return;
}
};

// Write out HTTP response
eprintln!("[success] successfully incremented [{counter}] counter");
Expand Down Expand Up @@ -264,7 +217,7 @@ fn write_http_response(
#[serde(untagged)]
pub enum ApiResponse {
Error { error: String },
Success { counter: i32 },
Success { counter: u64 },
}

impl ApiResponse {
Expand All @@ -276,7 +229,7 @@ impl ApiResponse {
}

/// Generate an error response
fn success(counter: i32) -> Self {
fn success(counter: u64) -> Self {
ApiResponse::Success { counter }
}

Expand Down

0 comments on commit daf7fdd

Please sign in to comment.