-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KeyValue atomic delete and purge methods. #271
Comments
Moving this to the architecture repo since it's feature request that would apply to all clients. |
Thanks Scott! That makes sense. By the way, I found that at least the go client already has this capability. I've edited the proposal to include this detail. Our offer to submit a contribution to the Java client is standing if the maintainers confirm the proposed approach. |
Yes happy to have this everywhere if go has it already 👍 |
@davidmcote Yes, contributions are encouraged! Please make sure to verify your commits. I made an issue in the repo: nats-io/nats.java#1091 |
Thanks for pointing this out @davidmcote! That would be an awesome addition, as I already use this for |
agree. This is a good think to have across the languages. @davidmcote I allowed myself to edit your issue and add our standard checks for cross-language support. |
done for the JavaScript clients. nats-io/nats.deno#656 |
Motivation
NATS clients provide the KeyValue interface with methods for optimistic atomic updates. (Eg: In Java, KeyValue.update(key, value, expectedRevision))
There doesn’t appear to be a way to specify an expectedRevision for delete() or purge(), neither in Java nor in the NATS cli.
However, I am able to craft a
nats req
forKV-Operation:DEL
which specifiesNats-Expected-Last-Subject-Sequence
and works in the expected manner: only writing a tombstone when the expectedRevision still matches.There doesn't appear to be any technical limitations in JetStream for supporting an atomic delete on KV keys.
Indeed, it looks like this capability is already present in the go client: https://github.com/nats-io/nats.go/blob/main/jetstream/kv.go#L134
Proposed change
Define two new methods in the KeyValue interface and corresponding implementations of these methods in NatsKeyValue.
These methods would enforce
expectedRevision
in the same manner aslong update(String key, byte[] value, long expectedRevision)
: by settingEXPECTED_LAST_SUB_SEQ_HDR
and propagating the exception from_write()
if the JetStream server rejects the request.Use case
Optimistic/atomic delete & purge of a KV entry.
As a specific example: A simple distributed locking mechanism can be built upon a KV bucket with TTL with the following rules:
Without an atomic delete, clients must instead release their lock by either using the non-atomic
delete()
method, or passively allowing the TTL to expire.This opens up a race condition where:
delete()
, expecting to relinquish its own lock.Contribution
My team has implemented our own atomic delete for KeyValue using the lower level
JetStream.publish()
method in our application which seems to be working for us. But we'd really prefer to be using an "official" KeyValue interface.If NATS maintainers agree with the implementation proposed above or have suggestions on the approach, we could submit this contribution.
EDIT (by @Jarema ):
As we accepted this to be part of all clients, I'm adding standard checklist:
Clients and Tools
Other Tasks
Implemented
Client authors please update with your progress. If you open issues in your own repositories as a result of this request, please link them to this one by pasting the issue URL in a comment or main issue description.
The text was updated successfully, but these errors were encountered: