The Key/Value Store is a JetStream feature, so we need to verify it is enabled by
which may return
In this case, you should enable JetStream.
If you are running a local nats-server stop it and restart it with JetStream enabled using nats-server -js (if that's not already done)
You can then check that JetStream is enabled by using
A 'KV bucket' is like a stream; you need to create it before using it, as in nats kv add <KV Bucket Name>:
Now that we have a bucket, we can assign, or 'put', a value to a specific key:
which should return the key's value Value1
We can fetch, or 'get', the value for a key "Key1":
You can always delete a key and its value by using
It is harmless to delete a non-existent key (check this!!).
K/V Stores can also be used in concurrent design patterns, such as semaphores, by using atomic 'create' and 'update' operations.
E.g. a client wanting exclusive use of a file can lock it by creating a key, whose value is the file name, with create and deleting this key after completing use of that file. A client can increase the reslience against failure by using a timeout for the bucket containing this key. The client can use update with a revision number to keep the bucket alive.
Updates can also be used for more fine-grained concurrency control, sometimes known as optimistic locking, where multiple clients can try a task, but only one can successfully complete it.
Create a lock/semaphore with the create operation.
Only one create can succeed. First come, first serve. All concurrent attempts will result in an error until the key is deleted
We can also atomically update, sometimes known as a CAS (compare and swap) operation, a key with an additional parameter revision
A second attempt with the same revision 13, will fail
An unusual functionality of a K/V Store is being able to 'watch' a bucket, or a specific key in that bucket, and receive real-time updates to changes in the store.
For the example above, run nats kv watch my-kv. This will start a watcher on the bucket we have just created earlier. By default, the KV bucket has a history size of one, and so it only remembers the last change. In our case, the watcher should see a delete of the value associated with the key "Key1":
If we now concurrently change the value of 'my-kv' by
The watcher will see that change:
When you are finished using a bucket, you can delete the bucket, and its resources, by using the rm operator: