Skip to content

Update CAS interface to remove current and add new-with-read #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ This proposal was inspired by Dapr's [State API]
[State API](https://docs.dapr.io/developing-applications/building-blocks/state-management/)

### Change log

- 2025-03-29:
- Modified `atomics` interface signature
- 2024-03-29:
- Simplified interfaces to 3 key pieces of functionality: store, atomics, and batch. Also removed
the use of streams to simplify the starting point of the API
Expand Down
23 changes: 12 additions & 11 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_draft2"><code>wasi:keyvalue/[email protected]draft2</code></a></li>
<li>interface <a href="#wasi_keyvalue_atomics_0_2_0_draft2"><code>wasi:keyvalue/[email protected]draft2</code></a></li>
<li>interface <a href="#wasi_keyvalue_batch_0_2_0_draft2"><code>wasi:keyvalue/[email protected]draft2</code></a></li>
<li>interface <a href="#wasi_keyvalue_store_0_2_0_draft3"><code>wasi:keyvalue/[email protected]draft3</code></a></li>
<li>interface <a href="#wasi_keyvalue_atomics_0_2_0_draft3"><code>wasi:keyvalue/[email protected]draft3</code></a></li>
<li>interface <a href="#wasi_keyvalue_batch_0_2_0_draft3"><code>wasi:keyvalue/[email protected]draft3</code></a></li>
</ul>
</li>
</ul>
<h2><a id="wasi_keyvalue_store_0_2_0_draft2"></a>Import interface wasi:keyvalue/[email protected]draft2</h2>
<h2><a id="wasi_keyvalue_store_0_2_0_draft3"></a>Import interface wasi:keyvalue/[email protected]draft3</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 @@ -178,7 +178,7 @@ for more information.</p>
<ul>
<li><a id="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 id="wasi_keyvalue_atomics_0_2_0_draft2"></a>Import interface wasi:keyvalue/[email protected]draft2</h2>
<h2><a id="wasi_keyvalue_atomics_0_2_0_draft3"></a>Import interface wasi:keyvalue/[email protected]draft3</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 @@ -226,16 +226,17 @@ latest version or transaction.
<ul>
<li><a id="static_cas_new.0"></a> result&lt;own&lt;<a href="#cas"><a href="#cas"><code>cas</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h4><a id="method_cas_current"></a><code>[method]cas.current: func</code></h4>
<p>Get the current value of the key (if it exists). This allows for avoiding reads if all
that is needed to ensure the atomicity of the operation</p>
<h4><a id="static_cas_new_with_read"></a><code>[static]cas.new_with_read: func</code></h4>
<p>Construct a new CAS operation returning the current value. Implementors can map the underlying functionality
(transactions, versions, etc) as desired.</p>
<h5>Params</h5>
<ul>
<li><a id="method_cas_current.self"></a><code>self</code>: borrow&lt;<a href="#cas"><a href="#cas"><code>cas</code></a></a>&gt;</li>
<li><a id="static_cas_new_with_read.bucket"></a><a href="#bucket"><code>bucket</code></a>: borrow&lt;<a href="#bucket"><a href="#bucket"><code>bucket</code></a></a>&gt;</li>
<li><a id="static_cas_new_with_read.key"></a><code>key</code>: <code>string</code></li>
</ul>
<h5>Return values</h5>
<ul>
<li><a id="method_cas_current.0"></a> result&lt;option&lt;list&lt;<code>u8</code>&gt;&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
<li><a id="static_cas_new_with_read.0"></a> result&lt;own&lt;<a href="#cas"><a href="#cas"><code>cas</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h4><a id="increment"></a><code>increment: func</code></h4>
<p>Atomically increment the value associated with the key in the store by the given delta. It
Expand Down Expand Up @@ -265,7 +266,7 @@ the CAS operation failed.</p>
<ul>
<li><a id="swap.0"></a> result&lt;_, <a href="#cas_error"><a href="#cas_error"><code>cas-error</code></a></a>&gt;</li>
</ul>
<h2><a id="wasi_keyvalue_batch_0_2_0_draft2"></a>Import interface wasi:keyvalue/[email protected]draft2</h2>
<h2><a id="wasi_keyvalue_batch_0_2_0_draft3"></a>Import interface wasi:keyvalue/[email protected]draft3</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
27 changes: 14 additions & 13 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_draft2"><code>wasi:keyvalue/[email protected]draft2</code></a></li>
<li>interface <a href="#wasi_keyvalue_atomics_0_2_0_draft2"><code>wasi:keyvalue/[email protected]draft2</code></a></li>
<li>interface <a href="#wasi_keyvalue_batch_0_2_0_draft2"><code>wasi:keyvalue/[email protected]draft2</code></a></li>
<li>interface <a href="#wasi_keyvalue_store_0_2_0_draft3"><code>wasi:keyvalue/[email protected]draft3</code></a></li>
<li>interface <a href="#wasi_keyvalue_atomics_0_2_0_draft3"><code>wasi:keyvalue/[email protected]draft3</code></a></li>
<li>interface <a href="#wasi_keyvalue_batch_0_2_0_draft3"><code>wasi:keyvalue/[email protected]draft3</code></a></li>
</ul>
</li>
<li>Exports:
<ul>
<li>interface <a href="#wasi_keyvalue_watcher_0_2_0_draft2"><code>wasi:keyvalue/[email protected]draft2</code></a></li>
<li>interface <a href="#wasi_keyvalue_watcher_0_2_0_draft3"><code>wasi:keyvalue/[email protected]draft3</code></a></li>
</ul>
</li>
</ul>
<h2><a id="wasi_keyvalue_store_0_2_0_draft2"></a>Import interface wasi:keyvalue/[email protected]draft2</h2>
<h2><a id="wasi_keyvalue_store_0_2_0_draft3"></a>Import interface wasi:keyvalue/[email protected]draft3</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 @@ -176,7 +176,7 @@ for more information.</p>
<ul>
<li><a id="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 id="wasi_keyvalue_atomics_0_2_0_draft2"></a>Import interface wasi:keyvalue/[email protected]draft2</h2>
<h2><a id="wasi_keyvalue_atomics_0_2_0_draft3"></a>Import interface wasi:keyvalue/[email protected]draft3</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 @@ -224,16 +224,17 @@ latest version or transaction.
<ul>
<li><a id="static_cas_new.0"></a> result&lt;own&lt;<a href="#cas"><a href="#cas"><code>cas</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h4><a id="method_cas_current"></a><code>[method]cas.current: func</code></h4>
<p>Get the current value of the key (if it exists). This allows for avoiding reads if all
that is needed to ensure the atomicity of the operation</p>
<h4><a id="static_cas_new_with_read"></a><code>[static]cas.new_with_read: func</code></h4>
<p>Construct a new CAS operation returning the current value. Implementors can map the underlying functionality
(transactions, versions, etc) as desired.</p>
<h5>Params</h5>
<ul>
<li><a id="method_cas_current.self"></a><code>self</code>: borrow&lt;<a href="#cas"><a href="#cas"><code>cas</code></a></a>&gt;</li>
<li><a id="static_cas_new_with_read.bucket"></a><a href="#bucket"><code>bucket</code></a>: borrow&lt;<a href="#bucket"><a href="#bucket"><code>bucket</code></a></a>&gt;</li>
<li><a id="static_cas_new_with_read.key"></a><code>key</code>: <code>string</code></li>
</ul>
<h5>Return values</h5>
<ul>
<li><a id="method_cas_current.0"></a> result&lt;option&lt;list&lt;<code>u8</code>&gt;&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
<li><a id="static_cas_new_with_read.0"></a> result&lt;own&lt;<a href="#cas"><a href="#cas"><code>cas</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h4><a id="increment"></a><code>increment: func</code></h4>
<p>Atomically increment the value associated with the key in the store by the given delta. It
Expand Down Expand Up @@ -263,7 +264,7 @@ the CAS operation failed.</p>
<ul>
<li><a id="swap.0"></a> result&lt;_, <a href="#cas_error"><a href="#cas_error"><code>cas-error</code></a></a>&gt;</li>
</ul>
<h2><a id="wasi_keyvalue_batch_0_2_0_draft2"></a>Import interface wasi:keyvalue/[email protected]draft2</h2>
<h2><a id="wasi_keyvalue_batch_0_2_0_draft3"></a>Import interface wasi:keyvalue/[email protected]draft3</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 @@ -342,7 +343,7 @@ fail.</p>
<ul>
<li><a id="delete_many.0"></a> result&lt;_, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
</ul>
<h2><a id="wasi_keyvalue_watcher_0_2_0_draft2"></a>Export interface wasi:keyvalue/[email protected]draft2</h2>
<h2><a id="wasi_keyvalue_watcher_0_2_0_draft3"></a>Export interface wasi:keyvalue/[email protected]draft3</h2>
<hr />
<h3>Types</h3>
<h4><a id="bucket"></a><code>type bucket</code></h4>
Expand Down
25 changes: 18 additions & 7 deletions wit/atomic.wit
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,30 @@ interface atomics {
/// A store error occurred when performing the operation
store-error(error),
/// The CAS operation failed because the value was too old. This returns a new CAS handle
/// for easy retries. Implementors MUST return a CAS handle that has been updated to the
/// for easy retries, as well as the current value for comparison. Implementors MUST return a CAS handle that has been updated to the
/// latest version or transaction.
cas-failed(cas),
cas-failed(tuple<cas,option<list<u8>>>),
}

/// A handle to a CAS (compare-and-swap) operation.
resource cas {
/// Construct a new CAS operation. Implementors can map the underlying functionality
/// (transactions, versions, etc) as desired.
/// Construct a new CAS handle for `key`.
///
/// This handle should guarantee that a subsequent `swap` operation will operate on data that has
/// not been modified since this call. If that condition is not met, `swap` should return `error`.
///
/// Note that this handle does not necessarily guarantee that no other operations occur on the key
/// after the handle is created, only that `error` is returned when calling `swap` if other operations did occur.
new: static func(bucket: borrow<bucket>, key: string) -> result<cas, error>;
/// Get the current value of the key (if it exists). This allows for avoiding reads if all
/// that is needed to ensure the atomicity of the operation
current: func() -> result<option<list<u8>>, error>;

/// Construct a new CAS handle returning the current value of `key`.
///
/// This handle should guarantee that a subsequent `swap` operation will operate on data that has
/// not been modified since this call. If that condition is not met, `swap` should return `error`.
///
/// Note that this handle does not necessarily guarantee that no other operations occur on the key
/// after the handle is created, only that `error` is returned when calling `swap` if other operations did occur.
new-with-read: static func(bucket: borrow<bucket>, key: string) -> result<tuple<cas, option<list<u8>>>, error>;
}

/// Atomically increment the value associated with the key in the store by the given delta. It
Expand Down
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:[email protected]draft2;
package wasi:[email protected]draft3;

/// 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