Skip to content

Commit 470a264

Browse files
committed
update wasi keyvalue to draft2
Signed-off-by: David Justice <[email protected]>
1 parent 1ed6467 commit 470a264

File tree

11 files changed

+285
-258
lines changed

11 files changed

+285
-258
lines changed

crates/factor-key-value/src/host.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -228,17 +228,20 @@ impl wasi_keyvalue::store::HostBucket for KeyValueDispatch {
228228
async fn list_keys(
229229
&mut self,
230230
self_: Resource<Bucket>,
231-
cursor: Option<u64>,
231+
cursor: Option<String>,
232232
) -> Result<wasi_keyvalue::store::KeyResponse, wasi_keyvalue::store::Error> {
233-
if cursor.unwrap_or_default() != 0 {
234-
return Err(wasi_keyvalue::store::Error::Other(
235-
"list_keys: cursor not supported".to_owned(),
236-
));
233+
match cursor {
234+
Some(_) => {
235+
Err(wasi_keyvalue::store::Error::Other(
236+
"list_keys: cursor not supported".to_owned(),
237+
))
238+
},
239+
None => {
240+
let store = self.get_store_wasi(self_)?;
241+
let keys = store.get_keys().await.map_err(to_wasi_err)?;
242+
Ok(wasi_keyvalue::store::KeyResponse { keys, cursor: None })
243+
}
237244
}
238-
239-
let store = self.get_store_wasi(self_)?;
240-
let keys = store.get_keys().await.map_err(to_wasi_err)?;
241-
Ok(wasi_keyvalue::store::KeyResponse { keys, cursor: None })
242245
}
243246

244247
async fn drop(&mut self, rep: Resource<Bucket>) -> anyhow::Result<()> {

wit/deps/keyvalue-2024-05-03/atomic.wit

Lines changed: 0 additions & 22 deletions
This file was deleted.

wit/deps/keyvalue-2024-05-03/batch.wit

Lines changed: 0 additions & 63 deletions
This file was deleted.

wit/deps/keyvalue-2024-05-03/store.wit

Lines changed: 0 additions & 122 deletions
This file was deleted.

wit/deps/keyvalue-2024-05-03/watch.wit

Lines changed: 0 additions & 16 deletions
This file was deleted.

wit/deps/keyvalue-2024-05-03/world.wit

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/// A keyvalue interface that provides atomic operations.
2+
///
3+
/// Atomic operations are single, indivisible operations. When a fault causes an atomic operation to
4+
/// fail, it will appear to the invoker of the atomic operation that the action either completed
5+
/// successfully or did nothing at all.
6+
///
7+
/// Please note that this interface is bare functions that take a reference to a bucket. This is to
8+
/// get around the current lack of a way to "extend" a resource with additional methods inside of
9+
/// wit. Future version of the interface will instead extend these methods on the base `bucket`
10+
/// resource.
11+
interface atomics {
12+
use store.{bucket, error};
13+
14+
/// The error returned by a CAS operation
15+
variant cas-error {
16+
/// A store error occurred when performing the operation
17+
store-error(error),
18+
/// The CAS operation failed because the value was too old. This returns a new CAS handle
19+
/// for easy retries. Implementors MUST return a CAS handle that has been updated to the
20+
/// latest version or transaction.
21+
cas-failed(cas),
22+
}
23+
24+
/// A handle to a CAS (compare-and-swap) operation.
25+
resource cas {
26+
/// Construct a new CAS operation. Implementors can map the underlying functionality
27+
/// (transactions, versions, etc) as desired.
28+
new: static func(bucket: borrow<bucket>, key: string) -> result<cas, error>;
29+
/// Get the current value of the key (if it exists). This allows for avoiding reads if all
30+
/// that is needed to ensure the atomicity of the operation
31+
current: func() -> result<option<list<u8>>, error>;
32+
}
33+
34+
/// Atomically increment the value associated with the key in the store by the given delta. It
35+
/// returns the new value.
36+
///
37+
/// If the key does not exist in the store, it creates a new key-value pair with the value set
38+
/// to the given delta.
39+
///
40+
/// If any other error occurs, it returns an `Err(error)`.
41+
increment: func(bucket: borrow<bucket>, key: string, delta: s64) -> result<s64, error>;
42+
43+
/// Perform the swap on a CAS operation. This consumes the CAS handle and returns an error if
44+
/// the CAS operation failed.
45+
swap: func(cas: cas, value: list<u8>) -> result<_, cas-error>;
46+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/// A keyvalue interface that provides batch operations.
2+
///
3+
/// A batch operation is an operation that operates on multiple keys at once.
4+
///
5+
/// Batch operations are useful for reducing network round-trip time. For example, if you want to
6+
/// get the values associated with 100 keys, you can either do 100 get operations or you can do 1
7+
/// batch get operation. The batch operation is faster because it only needs to make 1 network call
8+
/// instead of 100.
9+
///
10+
/// A batch operation does not guarantee atomicity, meaning that if the batch operation fails, some
11+
/// of the keys may have been modified and some may not.
12+
///
13+
/// This interface does has the same consistency guarantees as the `store` interface, meaning that
14+
/// you should be able to "read your writes."
15+
///
16+
/// Please note that this interface is bare functions that take a reference to a bucket. This is to
17+
/// get around the current lack of a way to "extend" a resource with additional methods inside of
18+
/// wit. Future version of the interface will instead extend these methods on the base `bucket`
19+
/// resource.
20+
interface batch {
21+
use store.{bucket, error};
22+
23+
/// Get the key-value pairs associated with the keys in the store. It returns a list of
24+
/// key-value pairs.
25+
///
26+
/// If any of the keys do not exist in the store, it returns a `none` value for that pair in the
27+
/// list.
28+
///
29+
/// MAY show an out-of-date value if there are concurrent writes to the store.
30+
///
31+
/// If any other error occurs, it returns an `Err(error)`.
32+
get-many: func(bucket: borrow<bucket>, keys: list<string>) -> result<list<option<tuple<string, list<u8>>>>, error>;
33+
34+
/// Set the values associated with the keys in the store. If the key already exists in the
35+
/// store, it overwrites the value.
36+
///
37+
/// Note that the key-value pairs are not guaranteed to be set in the order they are provided.
38+
///
39+
/// If any of the keys do not exist in the store, it creates a new key-value pair.
40+
///
41+
/// If any other error occurs, it returns an `Err(error)`. When an error occurs, it does not
42+
/// rollback the key-value pairs that were already set. Thus, this batch operation does not
43+
/// guarantee atomicity, implying that some key-value pairs could be set while others might
44+
/// fail.
45+
///
46+
/// Other concurrent operations may also be able to see the partial results.
47+
set-many: func(bucket: borrow<bucket>, key-values: list<tuple<string, list<u8>>>) -> result<_, error>;
48+
49+
/// Delete the key-value pairs associated with the keys in the store.
50+
///
51+
/// Note that the key-value pairs are not guaranteed to be deleted in the order they are
52+
/// provided.
53+
///
54+
/// If any of the keys do not exist in the store, it skips the key.
55+
///
56+
/// If any other error occurs, it returns an `Err(error)`. When an error occurs, it does not
57+
/// rollback the key-value pairs that were already deleted. Thus, this batch operation does not
58+
/// guarantee atomicity, implying that some key-value pairs could be deleted while others might
59+
/// fail.
60+
///
61+
/// Other concurrent operations may also be able to see the partial results.
62+
delete-many: func(bucket: borrow<bucket>, keys: list<string>) -> result<_, error>;
63+
}

0 commit comments

Comments
 (0)