Key-Value functionality of NATS can be accessed by creating the nats::key_value
TclOO object. Do not create it directly - instead, call the bind_kv_bucket or create_kv_bucket method of your nats::jet_stream
. Please refer to the official documentation for the description of general concepts.
kv get key ?-revision int?
kv get_value key ?-revision int?
kv put key value
kv create key value
kv update key value revision
kv delete key ?revision?
kv purge key
kv revert key revision
kv status
kv history key
kv keys
kv watch key args
kv destroy
The key_value
object provides access to a specific KV bucket. A bucket is merely a JS stream
that has some default options, and its name always starts with "KV_". And a key is, in fact, a (portion of) a subject that this stream listens to. Therefore, all KV operations are implemented in terms of standard JetStream operations such as publish
, stream_msg_get
etc. They all block in a (coroutine-aware) vwait
with the same timeout as in the parent jet_stream
.
NATS by Example provides a good overview of how KV buckets work on top of streams.
The naming rules of NATS subjects apply to keys as well, and keys can't start with "_kv".
You can access a KV bucket across JetStream domains and create KV mirrors as well. These concepts are explained in the chapters about NATS Leaf Nodes and Stream Replication.
A KV entry is a dict with the following fields:
bucket
key
value
- a value or an empty string if it is a DEL or PURGE entryrevision
- revision number, starting with 1 (seq
of the message in the underlying stream)created
- creation timestamp as milliseconds since the epochdelta
operation
- one ofPUT
,DEL
orPURGE
A bucket status is a dict with the following fields:
bucket
- namebytes
- size of the buckethistory
- number of history entries per keyttl
- for how long (ms) the bucket keeps values or 0 for unlimited timevalues
- total number of entries in the bucket including historical onesmirror_name
- optionalmirror_domain
- optionalstream_config
- configuration of the backing streamstream_state
- state of the backing stream
Returns the latest entry for the key
or the entry with the specified revision
. Throws ErrKeyNotFound
if the key doesn't exist or was deleted.
A shorthand for kv get
that returns only the value from the entry.
Puts the new value
for the key
. Returns the new revision number.
Creates a new key-value pair only if the key doesn't exist. Otherwise it throws ErrWrongLastSequence
. Returns the new revision number.
Updates the key
with the new value
only if the latest revision matches. In case of mismatch it throws ErrWrongLastSequence
. Returns the new revision number.
Deletes the key
, while preserving the history. If specified, the revision
must match the latest revision number.
Deletes the key
, removing all previous revisions.
Reverts a value to a previous revision
using kv put
. Returns the new revision number.
Returns the status of the KV bucket as described above.
Returns all historical entries for the key
. A NATS wildcard pattern can be used as well, e.g. ">" to get all entries in the bucket.
Returns all keys in the bucket. Throws ErrKeyNotFound
if the bucket is empty.
Starts watching the key
(that can be a NATS wildcard) and returns a new watcher
TclOO object. Destroy this object to stop watching.
KV entries can be delivered to a callback or to an array (or both):
-callback cmdPrefix
- deliver entries to this callback.-values_array varName
- deliver values to this array.varName
must be a fully qualified name.
At least, one of -callback
or -values_array
must be provided.
You can further refine what is delivered using these options:
-include_history bool
- deliver historical entries as well (default false).-meta_only bool
- deliver entries without values (default false). E.g. to watch for available keys.-ignore_deletes bool
- do not deliver DELETE and PURGE entries (default false).-updates_only bool
- deliver only updates (default false).
If you opt for the callback option, it will be invoked from the event loop with the following signature:
cmdPrefix entry
The callback is invoked in the following order, once for each entry:
- Historical entries for all matching keys (only with
-include_history=true
). - Current entries for all matching keys (if
-updates_only=false
). - Then it is invoked once again with an empty
entry
to signal "end of current data". - When a key is updated, it is invoked with a new entry.
If you opt for the array option:
- Current keys and values from the bucket are inserted into this array.
- Afterwards, updates in KV are delivered as they happen.
If a key is deleted or purged from the KV, and -ignore_deletes=false
, the corresponding key will be removed from the array as well.
Thus, you effectively have a local cache of a whole KV bucket or its portion that is always up-to-date. Depending on your use case, this might be more efficient than querying the bucket with [$kv get]
.
The array can't be a local variable.
TclOO destructor. Remember to call it before destroying the parent nats::jet_stream
.
KV-specific errors are listed in JsAPI.md