-
Notifications
You must be signed in to change notification settings - Fork 656
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
base: unstable
Are you sure you want to change the base?
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 ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## unstable #1324 +/- ##
============================================
+ Coverage 70.68% 70.76% +0.07%
============================================
Files 115 115
Lines 63177 63198 +21
============================================
+ Hits 44657 44722 +65
+ Misses 18520 18476 -44
|
Signed-off-by: Sarthak Aggarwal <[email protected]>
1840d02
to
0652f67
Compare
Signed-off-by: Sarthak Aggarwal <[email protected]>
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.
assert_equal {OK} [r set foo "new_value" ifeq "initial_value"] | ||
assert_equal "new_value" [r get foo] | ||
|
||
assert_equal {} [r set foo "should_not_set" ifeq "wrong_value"] |
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.
@valkey-io/core-team On failure of compare/set instead of nil value we should return an error with old value in it. Otherwise, a client would need to perform another GET operation.
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.
return an error with old value seems odd to me. i think in normal cases, a client is unlikely get an error in set IFEQ, they hold the old value in somewhere, and if the old value is unvalid, this mean client should abort the set, this usually means the client should abort the entire business logic. In this case, client should GET the new value as needed and usually they don't really need the new value, they juse want the result of whether the SET succeeded or not.
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.
@enjoy-binbin I understand if the value is updated from a DB to Valkey as a cache, the client won't benefit much from the value present.
However, if I think Valkey being used as a datastore and value is updated by multiple clients based on the value stored (let say increment old value by 1). for this case, they would need to know the previous value.
Let's hear other devs opinion on this and resolve this.
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]>
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).
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.
Behavior with this PR
If the values match, the SET completes as expected. If they do not match, the command returns a (nil).
Behavior with Additional Flags
SET <key> <value> IFEQ <comparison-value> GET
returns the existing value if present, (nil) if not and gives the error if there is a Type Mismatch. Conditional set operation is performed if the given comparison value matches the existing value.SET <key> <value> IFEQ <comparison-value> XX
returns nil if the key doesn't exist, otherwise conditionally updates the key if the given comparison value matches the existing value.SET <key> <value> IFEQ <comparison-value> NX
returns nil whether or not the key exists. Does not conditionally update the key ifNX
flag is presentAddresses: #1215