-
Notifications
You must be signed in to change notification settings - Fork 704
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
Set Command with IFEQ Support #1324
Set Command with IFEQ Support #1324
Conversation
c2dbcba
to
14c5fd9
Compare
6c216c1
to
ed26e4b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to think through the behavior with other flags/parameters of SET command https://valkey.io/commands/set/
NX -- Only set the key if it does not already exist
- should we error in this case if CAS is provided?
XX -- Only set the key if it already exists
- This becomes redundant to use I believe with CAS.
GET -- Return the old string stored at key, or nil if key did not exist. An error is returned and SET aborted if the value stored at key is not a string.
- I think we need to support this parameter in some form. The scenario which comes to my mind is when CAS fails and a user doesn't need to send a GET command again to find out the value stored in the engine. However, we need to think about how to differentiate between success scenario vs failure scenario.
Also, we need to document them.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## unstable #1324 +/- ##
============================================
- Coverage 70.85% 70.83% -0.02%
============================================
Files 118 118
Lines 63591 63611 +20
============================================
+ Hits 45058 45062 +4
- Misses 18533 18549 +16
|
0652f67
to
b7ed294
Compare
@sarthakaggarwal97 Please avoid force pushing. force push removes the reviewer's history in Github and one needs to look at the entire change again. |
noted @hpatro, will avoid it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sarthakaggarwal97 for the PR! Looks pretty good. Could you also document the behavior in the top comment. Will be easier for others to review and we can finalize it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM overall. The behavior currently is:
- if value matches, set the new value.
- If existing value is of different type, return error
WRONGTYPE Operation against a key holding the wrong kind of value
- if existing value is a mismatch, return nil. (want us to finalize on this).
Let's make IFEQ mutually exclusive with NX and XX. It doesn't make sense to combine them so let's make it a syntax error now. (If we don't, we can't fix it in the future without a breaking change.)
In the JSON file, putting them in the same "oneOf" block, this is also used for the website and man pages where the syntax is rendered. Regarding the combining IFEQ with the GET parameter will be difficult to use, but not impossible with the behaviour you described. If SET replied with the 'comparison-value', it means the SET has succeeded. I think it's logical, even if it will probably be very rarely used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks pretty good. Just don't want to allow IFEQ combined with NX and XX.
62b8832
to
66ad52d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, LGTM now.
Just a few nits. Not a blocker for merging.
@madolson @hpatro @enjoy-binbin Let's finalize the exact behavior with the various flags. This is the currently implemented logic:
Please confirm ( 👍 ) or protest ( 😱 ). |
What I like about this is, it's opt in. If the user actually wants the old value only then they get it. And, if the stored value is large, they could choose to not get it back. |
Signed-off-by: Sarthak Aggarwal <[email protected]>
Signed-off-by: Sarthak Aggarwal <[email protected]>
Signed-off-by: Sarthak Aggarwal <[email protected]>
Signed-off-by: Sarthak Aggarwal <[email protected]>
Signed-off-by: Sarthak Aggarwal <[email protected]>
Signed-off-by: Sarthak Aggarwal <[email protected]>
Signed-off-by: Sarthak Aggarwal <[email protected]>
07eaf76
to
73a7463
Compare
We discussed this a bit in the weekly meeting, a callout was that we want to make sure that clients add support for this. The most significant callout was that there is some uncertainty now if this is the right API. The ask was that we should spend more time to figure out if this is the best way to solve the original use cases, so if we could create some examples in the documentation page about what problem this solves and why it's better than LUA or multi, we will follow up. @hpatro and @sarthakaggarwal97 let me know if you have any questions. |
Client changes? That's only if the client does some detailed wrapping of each and every command argument, right? Is that really considered good practice? I would like to call it an anti-pattern. No changes are needed for any of the clients I've been involved in: libvalkey (hiredis-fork), valkey-cli and ered (an Erlang client). A command line is just represented as a list of strings and called like |
When using |
For simple use cases, it's simpler than Lua and WATCH + MULTI. It's also faster. (With WATCH + MULTI you need two round trips to the server.) |
This PR adds the documentation to support valkey-io/valkey#1324 --------- Signed-off-by: Sarthak Aggarwal <[email protected]> Signed-off-by: Viktor Söderqvist <[email protected]> Co-authored-by: Viktor Söderqvist <[email protected]>
I mean, I'll pin it for a future discussion, but all of the GLIDE clients have fully typed inputs and outputs so that it's easier for developers to see what the output will look like instead of having to infer it. |
This PR allows the Valkey users to perform conditional updates where the SET command is completed if the given comparison-value matches the key’s current value. Syntax: ``` SET key value IFEQ comparison-value ``` Behavior: If the values match, the SET completes as expected. If they do not match, the command returns a (nil), except if the GET argument is also given (see below). Behavior with Additional Flags: 1. ```SET key value IFEQ comparison-value GET``` returns the existing value, regardless of whether it matches comparison-value or not. The conditional set operation is performed if the given comparison value matches the existing value. To check if the SET succeeded, the caller needs to check if the returned string matches the comparison-value. 2. ```SET key value IFEQ comparison-value XX``` is a syntax error. 3. ```SET key value IFEQ comparison-value NX``` is a syntax error. Closes: valkey-io#1215 --------- Signed-off-by: Sarthak Aggarwal <[email protected]>
I think @soloestoy's question in #1415 is about semantics, i.e., |
Implement the new `IFEQ` `SET` option that will be included in `Valkey` 8.1. See: valkey-io/valkey#1324
Implement the new `IFEQ` `SET` option that will be included in `Valkey` 8.1. See: valkey-io/valkey#1324
Implement the new `IFEQ` `SET` option that will be included in `Valkey` 8.1. See: valkey-io/valkey#1324
Implement the new `IFEQ` `SET` option that will be included in `Valkey` 8.1. See: valkey-io/valkey#1324
This PR allows the Valkey users to perform conditional updates where the SET command is completed if the given comparison-value matches the key’s current value.
Syntax:
Behavior:
If the values match, the SET completes as expected. If they do not match, the command returns a (nil), except if the GET argument is also given (see below).
Behavior with Additional Flags:
SET key value IFEQ comparison-value GET
returns the existing value, regardless of whether it matches comparison-value or not. The conditional set operation is performed if the given comparison value matches the existing value. To check if the SET succeeded, the caller needs to check if the returned string matches the comparison-value.SET key value IFEQ comparison-value XX
is a syntax error.SET key value IFEQ comparison-value NX
is a syntax error.Closes: #1215