Skip to content

Commit 2cc7ed0

Browse files
committed
remove read-your-writes guarantee
This removes the "read-your-writes" guarantee since several of the backing stores we wish to support either do not support it or do not support it by default. Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent 94183c2 commit 2cc7ed0

1 file changed

Lines changed: 34 additions & 27 deletions

File tree

wit/store.wit

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,51 +10,58 @@
1010
///
1111
/// ## Consistency
1212
///
13-
/// Any implementation of this interface MUST have enough consistency to guarantee "reading your
14-
/// writes" for read operations on the same `bucket` resource instance. Reads from `bucket`
15-
/// resources other than the one used to write are _not_ guaranteed to return the written value
16-
/// given that the other resources may be connected to other replicas in a distributed system, even
17-
/// when opened using the same bucket identifier.
13+
/// An implementation of this interface MUST be eventually consistent, meaning that, after some time
14+
/// with no further updates, all replicas in the (potentially distributed) system will eventually
15+
/// converge on a consistent state for all values. This allows replicas to temporarily diverge to
16+
/// ensure low latency and high availability. Implementations based on a centralized or local
17+
/// backing store may provide a stronger consistency model, but guest components which are intended
18+
/// to be portable to any `wasi-keyvalue` implementation should not rely on anything stronger than
19+
/// eventual consistency.
1820
///
19-
/// In particular, this means that a `get` call for a given key on a given `bucket`
20-
/// resource MUST never return a value that is older than the the last value written to that key
21-
/// on the same resource, but it MAY get a newer value if one was written around the same
22-
/// time. These guarantees only apply to reads and writes on the same resource; they do not hold
23-
/// across multiple resources -- even when those resources were opened using the same string
24-
/// identifier by the same component instance.
21+
/// Given that each `bucket` resource may represent a connection to a different replica in a
22+
/// distributed system, values read for a given key from two different `bucket`s may differ, even if
23+
/// those `bucket` resources were opened using the same string identifier. In addition, consecutive
24+
/// operations on a single `bucket` resource may produce temporarily inconsistent results if
25+
/// e.g. the implementation is forced to reconnect to a different replica due to a connection
26+
/// failure. For example, a write followed by a read may not return the value just written, even if
27+
/// no other recent or subsequent writes have occurred.
2528
///
26-
/// The following pseudocode example illustrates this behavior. Note that we assume there is
27-
/// initially no value set for any key and that no other writes are happening beyond what is shown
28-
/// in the example.
29+
/// Consider the following pseudocode example (and assume we start with an empty store and no other
30+
/// concurrent activity):
2931
///
32+
/// ```
3033
/// bucketA = open("foo")
3134
/// bucketB = open("foo")
3235
/// bucketA.set("bar", "a")
33-
/// // The following are guaranteed to succeed:
34-
/// assert bucketA.get("bar").equals("a")
36+
///
37+
/// // These are guaranteed to succeed:
38+
/// assert bucketA.get("bar").equals("a") or bucketA.get("bar") is None
3539
/// assert bucketB.get("bar").equals("a") or bucketB.get("bar") is None
36-
/// // ...whereas this is NOT guaranteed to succeed immediately (but SHOULD eventually):
37-
/// // assert bucketB.get("bar").equals("a")
3840
///
39-
/// Once a value is `set` for a given key on a given `bucket` resource, all subsequent `get`
40-
/// requests on that same resource will reflect that write or any subsequent writes. `get` requests
41-
/// using a different bucket may or may not immediately see the new value due to e.g. cache effects
42-
/// and/or replication lag.
41+
/// // This is likely to succeed, but not guaranteed; e.g. `bucketA` might need to reconnect to a
42+
/// // different replica which hasn't received the above write yet. It will _eventually_
43+
/// // succeed, provided there are no irrecoverable errors which prevent the propagation of the
44+
/// // write.
45+
/// assert bucketA.get("bar").equals("a")
4346
///
44-
/// Continuing the above example:
47+
/// // Likewise, this will _eventually_ succeed in the absence of irrecoverable errors:
48+
/// assert bucketB.get("bar").equals("a")
4549
///
4650
/// bucketB.set("bar", "b")
4751
/// bucketC = open("foo")
4852
/// value = bucketC.get("bar")
53+
///
54+
/// // This is guaranteed to succeed:
4955
/// assert value.equals("a") or value.equals("b") or value is None
56+
/// ```
5057
///
5158
/// In other words, the `bucketC` resource MAY reflect either the most recent write to the `bucketA`
5259
/// resource, or the one to the `bucketB` resource, or neither, depending on how quickly either of
5360
/// those writes reached the replica from which the `bucketC` resource is reading. However,
54-
/// assuming there are no unrecoverable errors -- such that the state of a replica is irretrievably
55-
/// lost before it can be propagated -- one of the values ("a" or "b") SHOULD eventually be
56-
/// considered the "latest" and replicated across the system, at which point all three resources
57-
/// will return that same value.
61+
/// assuming there are no irrecoverable errors -- such that the state of a replica is irretrievably
62+
/// lost before it can be propagated -- one of the values ("a" or "b") MUST eventually be considered
63+
/// the "latest" and replicated across the system, at which point all three resources will return
64+
/// that same value.
5865
///
5966
/// ## Durability
6067
///

0 commit comments

Comments
 (0)