Skip to content

Commit

Permalink
feat(*)!: Adds cas operation and fixes keys cursor
Browse files Browse the repository at this point in the history
This PR incorporates some feedback received on the current draft interface.
First off, this changes the cursor for listing keys to be a string instead
of a number in order to support more systems.

The second changes adds back in a CAS operation as multiple people had
been asking for it. See the discussion in WebAssembly#44 for more context.

Because these are breaking changes and there are multiple draft
implementations out there, I bumped this to draft2. Ideally we should be
able to move to an RC soon with these changes added in

Closes WebAssembly#44
Closes WebAssembly#45

Signed-off-by: Taylor Thomas <taylor@cosmonic.com>
  • Loading branch information
thomastaylor312 committed Jul 29, 2024
1 parent 219ea36 commit e24291a
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 21 deletions.
32 changes: 24 additions & 8 deletions imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ Components targeting this world will be able to do:</p>
<ul>
<li>Imports:
<ul>
<li>interface <a href="#wasi:keyvalue_store_0.2.0_draft"><code>wasi:keyvalue/store@0.2.0-draft</code></a></li>
<li>interface <a href="#wasi:keyvalue_atomics_0.2.0_draft"><code>wasi:keyvalue/atomics@0.2.0-draft</code></a></li>
<li>interface <a href="#wasi:keyvalue_batch_0.2.0_draft"><code>wasi:keyvalue/batch@0.2.0-draft</code></a></li>
<li>interface <a href="#wasi:keyvalue_store_0.2.0_draft2"><code>wasi:keyvalue/store@0.2.0-draft2</code></a></li>
<li>interface <a href="#wasi:keyvalue_atomics_0.2.0_draft2"><code>wasi:keyvalue/atomics@0.2.0-draft2</code></a></li>
<li>interface <a href="#wasi:keyvalue_batch_0.2.0_draft2"><code>wasi:keyvalue/batch@0.2.0-draft2</code></a></li>
</ul>
</li>
</ul>
<h2><a name="wasi:keyvalue_store_0.2.0_draft"></a>Import interface wasi:keyvalue/store@0.2.0-draft</h2>
<h2><a name="wasi:keyvalue_store_0.2.0_draft2"></a>Import interface wasi:keyvalue/store@0.2.0-draft2</h2>
<p>A keyvalue interface that provides eventually consistent key-value operations.</p>
<p>Each of these operations acts on a single key-value pair.</p>
<p>The value in the key-value pair is defined as a <code>u8</code> byte array and the intention is that it is
Expand Down Expand Up @@ -66,7 +66,7 @@ still see A or B</p>
<p>The list of keys returned by the query.
</li>
<li>
<p><a name="key_response.cursor"></a><code>cursor</code>: option&lt;<code>u64</code>&gt;</p>
<p><a name="key_response.cursor"></a><code>cursor</code>: option&lt;<code>string</code>&gt;</p>
<p>The continuation token to use to fetch the next page of keys. If this is `null`, then
there are no more keys to fetch.
</li>
Expand Down Expand Up @@ -172,13 +172,13 @@ for more information.</p>
<h5>Params</h5>
<ul>
<li><a name="method_bucket.list_keys.self"></a><code>self</code>: borrow&lt;<a href="#bucket"><a href="#bucket"><code>bucket</code></a></a>&gt;</li>
<li><a name="method_bucket.list_keys.cursor"></a><code>cursor</code>: option&lt;<code>u64</code>&gt;</li>
<li><a name="method_bucket.list_keys.cursor"></a><code>cursor</code>: option&lt;<code>string</code>&gt;</li>
</ul>
<h5>Return values</h5>
<ul>
<li><a name="method_bucket.list_keys.0"></a> result&lt;<a href="#key_response"><a href="#key_response"><code>key-response</code></a></a>, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h2><a name="wasi:keyvalue_atomics_0.2.0_draft"></a>Import interface wasi:keyvalue/atomics@0.2.0-draft</h2>
<h2><a name="wasi:keyvalue_atomics_0.2.0_draft2"></a>Import interface wasi:keyvalue/atomics@0.2.0-draft2</h2>
<p>A keyvalue interface that provides atomic operations.</p>
<p>Atomic operations are single, indivisible operations. When a fault causes an atomic operation to
fail, it will appear to the invoker of the atomic operation that the action either completed
Expand Down Expand Up @@ -213,7 +213,23 @@ to the given delta.</p>
<ul>
<li><a name="increment.0"></a> result&lt;<code>u64</code>, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h2><a name="wasi:keyvalue_batch_0.2.0_draft"></a>Import interface wasi:keyvalue/batch@0.2.0-draft</h2>
<h4><a name="compare_and_swap"></a><code>compare-and-swap: func</code></h4>
<p>Atomically set the value associated with the key in the store to the given value. It returns
<code>true</code> if the value was set properly, or <code>false</code> if the swap failed.</p>
<p>If setting a new value, a <code>none</code> value should be passed for the <code>old</code> parameter. If the key
already exists in the store, it will be swapped with the new value only if the current value
is equal to the old value. To delete a key-value pair, pass <code>none</code> for the <code>new</code> parameter.</p>
<h5>Params</h5>
<ul>
<li><a name="compare_and_swap.key"></a><code>key</code>: <code>string</code></li>
<li><a name="compare_and_swap.old"></a><code>old</code>: option&lt;list&lt;<code>u8</code>&gt;&gt;</li>
<li><a name="compare_and_swap.new"></a><code>new</code>: option&lt;list&lt;<code>u8</code>&gt;&gt;</li>
</ul>
<h5>Return values</h5>
<ul>
<li><a name="compare_and_swap.0"></a> result&lt;<code>bool</code>, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h2><a name="wasi:keyvalue_batch_0.2.0_draft2"></a>Import interface wasi:keyvalue/batch@0.2.0-draft2</h2>
<p>A keyvalue interface that provides batch operations.</p>
<p>A batch operation is an operation that operates on multiple keys at once.</p>
<p>Batch operations are useful for reducing network round-trip time. For example, if you want to
Expand Down
36 changes: 26 additions & 10 deletions watch-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
<ul>
<li>Imports:
<ul>
<li>interface <a href="#wasi:keyvalue_store_0.2.0_draft"><code>wasi:keyvalue/store@0.2.0-draft</code></a></li>
<li>interface <a href="#wasi:keyvalue_atomics_0.2.0_draft"><code>wasi:keyvalue/atomics@0.2.0-draft</code></a></li>
<li>interface <a href="#wasi:keyvalue_batch_0.2.0_draft"><code>wasi:keyvalue/batch@0.2.0-draft</code></a></li>
<li>interface <a href="#wasi:keyvalue_store_0.2.0_draft2"><code>wasi:keyvalue/store@0.2.0-draft2</code></a></li>
<li>interface <a href="#wasi:keyvalue_atomics_0.2.0_draft2"><code>wasi:keyvalue/atomics@0.2.0-draft2</code></a></li>
<li>interface <a href="#wasi:keyvalue_batch_0.2.0_draft2"><code>wasi:keyvalue/batch@0.2.0-draft2</code></a></li>
</ul>
</li>
<li>Exports:
<ul>
<li>interface <a href="#wasi:keyvalue_watcher_0.2.0_draft"><code>wasi:keyvalue/watcher@0.2.0-draft</code></a></li>
<li>interface <a href="#wasi:keyvalue_watcher_0.2.0_draft2"><code>wasi:keyvalue/watcher@0.2.0-draft2</code></a></li>
</ul>
</li>
</ul>
<h2><a name="wasi:keyvalue_store_0.2.0_draft"></a>Import interface wasi:keyvalue/store@0.2.0-draft</h2>
<h2><a name="wasi:keyvalue_store_0.2.0_draft2"></a>Import interface wasi:keyvalue/store@0.2.0-draft2</h2>
<p>A keyvalue interface that provides eventually consistent key-value operations.</p>
<p>Each of these operations acts on a single key-value pair.</p>
<p>The value in the key-value pair is defined as a <code>u8</code> byte array and the intention is that it is
Expand Down Expand Up @@ -64,7 +64,7 @@ still see A or B</p>
<p>The list of keys returned by the query.
</li>
<li>
<p><a name="key_response.cursor"></a><code>cursor</code>: option&lt;<code>u64</code>&gt;</p>
<p><a name="key_response.cursor"></a><code>cursor</code>: option&lt;<code>string</code>&gt;</p>
<p>The continuation token to use to fetch the next page of keys. If this is `null`, then
there are no more keys to fetch.
</li>
Expand Down Expand Up @@ -170,13 +170,13 @@ for more information.</p>
<h5>Params</h5>
<ul>
<li><a name="method_bucket.list_keys.self"></a><code>self</code>: borrow&lt;<a href="#bucket"><a href="#bucket"><code>bucket</code></a></a>&gt;</li>
<li><a name="method_bucket.list_keys.cursor"></a><code>cursor</code>: option&lt;<code>u64</code>&gt;</li>
<li><a name="method_bucket.list_keys.cursor"></a><code>cursor</code>: option&lt;<code>string</code>&gt;</li>
</ul>
<h5>Return values</h5>
<ul>
<li><a name="method_bucket.list_keys.0"></a> result&lt;<a href="#key_response"><a href="#key_response"><code>key-response</code></a></a>, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h2><a name="wasi:keyvalue_atomics_0.2.0_draft"></a>Import interface wasi:keyvalue/atomics@0.2.0-draft</h2>
<h2><a name="wasi:keyvalue_atomics_0.2.0_draft2"></a>Import interface wasi:keyvalue/atomics@0.2.0-draft2</h2>
<p>A keyvalue interface that provides atomic operations.</p>
<p>Atomic operations are single, indivisible operations. When a fault causes an atomic operation to
fail, it will appear to the invoker of the atomic operation that the action either completed
Expand Down Expand Up @@ -211,7 +211,23 @@ to the given delta.</p>
<ul>
<li><a name="increment.0"></a> result&lt;<code>u64</code>, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h2><a name="wasi:keyvalue_batch_0.2.0_draft"></a>Import interface wasi:keyvalue/batch@0.2.0-draft</h2>
<h4><a name="compare_and_swap"></a><code>compare-and-swap: func</code></h4>
<p>Atomically set the value associated with the key in the store to the given value. It returns
<code>true</code> if the value was set properly, or <code>false</code> if the swap failed.</p>
<p>If setting a new value, a <code>none</code> value should be passed for the <code>old</code> parameter. If the key
already exists in the store, it will be swapped with the new value only if the current value
is equal to the old value. To delete a key-value pair, pass <code>none</code> for the <code>new</code> parameter.</p>
<h5>Params</h5>
<ul>
<li><a name="compare_and_swap.key"></a><code>key</code>: <code>string</code></li>
<li><a name="compare_and_swap.old"></a><code>old</code>: option&lt;list&lt;<code>u8</code>&gt;&gt;</li>
<li><a name="compare_and_swap.new"></a><code>new</code>: option&lt;list&lt;<code>u8</code>&gt;&gt;</li>
</ul>
<h5>Return values</h5>
<ul>
<li><a name="compare_and_swap.0"></a> result&lt;<code>bool</code>, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h2><a name="wasi:keyvalue_batch_0.2.0_draft2"></a>Import interface wasi:keyvalue/batch@0.2.0-draft2</h2>
<p>A keyvalue interface that provides batch operations.</p>
<p>A batch operation is an operation that operates on multiple keys at once.</p>
<p>Batch operations are useful for reducing network round-trip time. For example, if you want to
Expand Down Expand Up @@ -290,7 +306,7 @@ fail.</p>
<ul>
<li><a name="delete_many.0"></a> result&lt;_, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h2><a name="wasi:keyvalue_watcher_0.2.0_draft"></a>Export interface wasi:keyvalue/watcher@0.2.0-draft</h2>
<h2><a name="wasi:keyvalue_watcher_0.2.0_draft2"></a>Export interface wasi:keyvalue/watcher@0.2.0-draft2</h2>
<hr />
<h3>Types</h3>
<h4><a name="bucket"></a><code>type bucket</code></h4>
Expand Down
8 changes: 8 additions & 0 deletions wit/atomic.wit
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ interface atomics {
///
/// If any other error occurs, it returns an `Err(error)`.
increment: func(bucket: borrow<bucket>, key: string, delta: u64) -> result<u64, error>;

/// Atomically set the value associated with the key in the store to the given value. It returns
/// `true` if the value was set properly, or `false` if the swap failed.
///
/// If setting a new value, a `none` value should be passed for the `old` parameter. If the key
/// already exists in the store, it will be swapped with the new value only if the current value
/// is equal to the old value. To delete a key-value pair, pass `none` for the `new` parameter.
compare-and-swap: func(key: string, old: option<list<u8>>, new: option<list<u8>>) -> result<bool, error>;
}
4 changes: 2 additions & 2 deletions wit/store.wit
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ interface store {
keys: list<string>,
/// The continuation token to use to fetch the next page of keys. If this is `null`, then
/// there are no more keys to fetch.
cursor: option<u64>
cursor: option<string>
}

/// Get the bucket with the specified identifier.
Expand Down Expand Up @@ -117,6 +117,6 @@ interface store {
/// MAY show an out-of-date list of keys if there are concurrent writes to the store.
///
/// If any error occurs, it returns an `Err(error)`.
list-keys: func(cursor: option<u64>) -> result<key-response, error>;
list-keys: func(cursor: option<string>) -> result<key-response, error>;
}
}
2 changes: 1 addition & 1 deletion wit/world.wit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package wasi:keyvalue@0.2.0-draft;
package wasi:keyvalue@0.2.0-draft2;

/// The `wasi:keyvalue/imports` world provides common APIs for interacting with key-value stores.
/// Components targeting this world will be able to do:
Expand Down

0 comments on commit e24291a

Please sign in to comment.