brazier/store
Types
A list store — any number of values per key. Appending the same value twice stores it twice. Auto-broadcasts on append/delete.
A local list store is an ETS duplicate_bag and get_all returns
values in insertion order. A replicated one returns them in timestamp
order (see open_list).
pub type ListStore(value) {
ListStore(
table: @internal EtsTable,
topic: String,
writer: Writer,
)
}
Constructors
-
ListStore( table: @internal EtsTable, topic: String, writer: Writer, )
Where a store’s data lives.
pub type Mode {
Local
Replicated(replicated.Config)
}
Constructors
-
LocalOne table per node; writes and notifications stay on the node.
-
Replicated(replicated.Config)A replica on every node that opens the store, kept convergent.
Why open / open_list failed.
pub type OpenError {
InvalidStore(StoreError)
InvalidConfig(reason: String)
StartFailed(reason: String)
}
Constructors
-
InvalidStore(StoreError)The name is invalid, or a table of that name exists with another type.
-
InvalidConfig(reason: String)The replicated configuration is out of range, or the store is already open in another mode or with a different configuration.
-
StartFailed(reason: String)The replica process failed to start.
Why a store could not be created or reused. name is the store’s
table name: the store name with its prefix (brazier_store_ for a
Store, brazier_ls_ for a ListStore), which must be 1-255 bytes of
[A-Za-z0-9_-] (it becomes an ETS table atom).
pub type StoreError {
InvalidName(name: String, reason: String)
TableTypeMismatch(
name: String,
expected: String,
found: String,
)
TableOwnerUnavailable(name: String, reason: String)
}
Constructors
-
InvalidName(name: String, reason: String)The name is empty, too long, or has a character outside
[A-Za-z0-9_-]. -
TableTypeMismatch(name: String, expected: String, found: String)A table with this name already exists with a different type.
-
TableOwnerUnavailable(name: String, reason: String)The table owner could not create the table, for example because it crashed owning tables and the application has not restarted.
Why synced / list_synced has no answer.
pub type SyncedError {
NotReplicated(topic: String)
ReplicaFailed(replicated.WriteError)
}
Constructors
-
NotReplicated(topic: String)The store is
Local: it has no replicas to be in sync with.topicnames the store. -
ReplicaFailed(replicated.WriteError)The node’s replica did not answer (see
replicated.WriteError).
Why a write failed (see brazier/store/replicated.WriteError).
pub type WriteError =
replicated.WriteError
Values
pub fn append(
store: ListStore(value),
key: String,
value: value,
) -> Nil
Append a value. Auto-broadcasts to store-level watchers. Crashes the
caller (after logging) if the write fails; see try_append.
pub fn append_many(
store: ListStore(value),
key: String,
values: List(value),
) -> Nil
Append multiple values at once. Only broadcasts ONCE after all inserts.
Use this instead of calling append() in a loop. Crashes the caller
(after logging) if the write fails; see try_append_many.
pub fn append_notify(
store: ListStore(value),
key: String,
value: value,
topic_prefix: String,
) -> Nil
Append a value and broadcast to both the store topic AND a per-key topic.
The per-key topic is prefix <> key (e.g., “room:” <> “general” = “room:general”).
Use with brazier.subscriptions() for dynamic per-key subscriptions.
Crashes the caller (after logging) if the write fails; see
try_append_notify.
pub fn delete(store: Store(value), key: String) -> Nil
Delete a value by key. Auto-broadcasts to watchers. Crashes the caller
(after logging) if the write fails; see try_delete.
pub fn delete_all(store: ListStore(value), key: String) -> Nil
Delete all values for a key. Auto-broadcasts to store-level watchers.
Crashes the caller (after logging) if the write fails; see
try_delete_all.
pub fn delete_all_notify(
store: ListStore(value),
key: String,
topic_prefix: String,
) -> Nil
Delete all values for a key and broadcast to a per-key topic. Crashes
the caller (after logging) if the write fails; see
try_delete_all_notify.
pub fn describe_error(err: StoreError) -> String
A human-readable description of a store error, for logs and messages.
pub fn get(
store: Store(value),
key: String,
) -> Result(value, Nil)
Get a value by key.
A replicated store reads its node’s replica. If that replica is down (restarting), the read is logged and crashes the caller.
pub fn get_all(
store: ListStore(value),
key: String,
) -> List(value)
Get all values for a key. Reads like get.
pub fn list_synced(
store: ListStore(value),
) -> Result(Bool, SyncedError)
synced for a list store.
pub fn list_topic(store: ListStore(value)) -> String
Get the PubSub topic for this list store (return it from brazier.subscriptions).
pub fn new(name: String) -> Store(value)
Create (or reuse) a local key-value store. Calling it again with the same name returns the same store.
Store names are developer-supplied constants, so a failure (an invalid
name) is a programming error: it is logged and crashes the caller
loudly. Use try_new to handle it as a value.
pub fn new_list(name: String) -> ListStore(value)
Create (or reuse) a local list store. Calling it again with the same name returns the same store.
A failure (an invalid name) is a programming error: it is logged and
crashes the caller loudly. Use try_new_list to handle it as a value.
pub fn open(
name: String,
mode: Mode,
) -> Result(Store(value), OpenError)
Open (or reuse) a key-value store in the given mode.
pub fn open_list(
name: String,
mode: Mode,
) -> Result(ListStore(value), OpenError)
Open (or reuse) a list store in the given mode.
A replicated list store orders the values of a key by the hybrid logical clock timestamp of their append: insertion order for appends made on one node, and the same order on every node for concurrent appends on different nodes.
pub fn put(store: Store(value), key: String, value: value) -> Nil
Set a value by key. Auto-broadcasts to watchers. Crashes the caller
(after logging) if the write fails; see try_put.
pub fn synced(store: Store(value)) -> Result(Bool, SyncedError)
Whether this node’s replica of a replicated store is in sync with every
peer replica: each one last sent a digest equal to this replica’s (see
replicated.synced, which this asks). Ok(True) with no peer. Every
value written anywhere before those digests were sent is then readable
on this node. Each change into sync also emits
[brazier, store, synced] (docs/TELEMETRY.md).
A Local store is Error(NotReplicated(..)): it has no replicas, so
“in sync” has no meaning for it.
pub fn topic(store: Store(value)) -> String
Get the PubSub topic for this store (return it from brazier.subscriptions).
pub fn try_append(
store: ListStore(value),
key: String,
value: value,
) -> Result(Nil, replicated.WriteError)
Append a value, returning why the write failed.
pub fn try_append_many(
store: ListStore(value),
key: String,
values: List(value),
) -> Result(Nil, replicated.WriteError)
Append multiple values at once, returning why the write failed. In a replicated store the values are one write: all of them or none.
pub fn try_append_notify(
store: ListStore(value),
key: String,
value: value,
topic_prefix: String,
) -> Result(Nil, replicated.WriteError)
append_notify, returning why the write failed. The per-key topic is
checked before the write, so an invalid one writes nothing.
pub fn try_delete(
store: Store(value),
key: String,
) -> Result(Nil, replicated.WriteError)
Delete a value by key, returning why the write failed. In a replicated store a value written concurrently on another node survives the delete.
pub fn try_delete_all(
store: ListStore(value),
key: String,
) -> Result(Nil, replicated.WriteError)
Delete all values for a key, returning why the write failed. In a replicated store values appended concurrently on another node survive.
pub fn try_delete_all_notify(
store: ListStore(value),
key: String,
topic_prefix: String,
) -> Result(Nil, replicated.WriteError)
delete_all_notify, returning why the write failed.
pub fn try_new(name: String) -> Result(Store(value), StoreError)
Create (or reuse) a local key-value store, returning a typed error for an invalid name.
pub fn try_new_list(
name: String,
) -> Result(ListStore(value), StoreError)
Create (or reuse) a local list store, returning a typed error for an invalid name.
pub fn try_put(
store: Store(value),
key: String,
value: value,
) -> Result(Nil, replicated.WriteError)
Set a value by key, returning why the write failed.