Layer 0 — Objects¶
db.objects is a conditional key-value store of mutable objects. Each
stored object has an opaque, backend-native etag that changes on every
write. Every higher layer is built on these operations.
obj = await db.objects.get("config/app.json") # StoredObject(data, etag) | None
etag = await db.objects.put("config/app.json", data) # unconditional write
etag = await db.objects.put("config/app.json", data,
if_match=obj.etag) # compare-and-swap
etag = await db.objects.put("init/marker", b"",
if_absent=True) # put-if-absent
await db.objects.delete("config/app.json") # no-op if missing
keys = await db.objects.list("config/") # ascending
Write semantics¶
Call |
Succeeds when |
Returns on failure |
|---|---|---|
|
always |
— |
|
the stored etag still equals |
|
|
the key does not exist |
|
if_match and if_absent are mutually exclusive. A None result is not
an error: it means “you lost the race”. Re-read and decide what to do.
Data is raw bytes. Encode it however you like. If you want JSON
documents with a retry loop, the doc
primitive does the encoding for you.
Objects are linearizable per key: once a write is acknowledged, every subsequent read, from any process, observes it.
Watching a key¶
wait_for polls until a key appears, or until it changes from a known
etag:
# Wait for an approval object to exist.
approval = await db.objects.wait_for("signals/run-1/approval", timeout=300, poll_interval=2.0)
# Wait until a document changes from the version we last saw.
newer = await db.objects.wait_for("config/app.json", changed_from=obj.etag, timeout=60)
It costs one GET per interval and raises TimeoutError when time runs
out. Polling is the correctness mechanism: there is no push channel that
could drop a notification.
Reserved prefixes¶
log/, snapshots/, logs/, and txapplied/ belong to the engine.
get, put, and delete raise ValueError for keys under them, so
application objects can never corrupt a log.
Sync twins¶
Each method has a *_sync twin (get_sync, put_sync, delete_sync,
list_sync) for code without an event loop.