-
Notifications
You must be signed in to change notification settings - Fork 742
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
standalone -REDIRECT handles special case of MULTI context #895
Conversation
Signed-off-by: zhaozhao.zz <[email protected]>
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## unstable #895 +/- ##
============================================
+ Coverage 70.41% 70.44% +0.02%
============================================
Files 114 114
Lines 61736 61742 +6
============================================
+ Hits 43474 43495 +21
+ Misses 18262 18247 -15
|
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, rejectCommand seem better in this case.
In cluster, EXEC returns -EXECABORT if any command in the transaction returned MOVED instead of QUEUED. There's a test case here: https://github.com/valkey-io/valkey/blob/8.0.0-rc1/tests/unit/cluster/transactions-on-replica.tcl#L48 test "MULTI-EXEC with write operations is MOVED" {
$replica MULTI
catch {$replica HSET h b 4} err
assert {[string range $err 0 4] eq {MOVED}}
catch {$replica exec} err
assert {[string range $err 0 8] eq {EXECABORT}}
} I think standalone should behave similarly, i.e.
|
@zuiderkwast you are right, the scenario you mentioned is when
Currently, this PR also adopts this method to return |
I think follow the rejectCommand logic is fine, but my concern is if we should add or update the error message for this case. In this pr, although we update the code flow to rejectCommand style, the error message still keep "REDIRECT" |
I'm not sure. The documented behaviour is that EXEC should not fail in this case. It should just return the errors (redirects) within the array returned by EXEC. This is documented on the valkey-transactions man page:
It's not very good that some commands can succeed and some other commands can fail in the same transaction, but that seems to be the case in the example with -WRONGTYPE. For redirect after queueing, I would prefer that a client has some possibility to retry the transaction on the correct node. If we implement a good behaviour and document it, it is not unrealistic for clients to implement redirect of transactions. A transaction is usually sent in a pipeline anyway. (It can be a problem if WATCH is used though. WATCH is typically not in the same pipeline, as the user normally needs to check some value after WATCH-ing a key.) |
Looking at the test cases in In standalone mode, this happens e.g. when the role changes after write commands have already been queued successfully (
At least, the behavior I described above is not contradicting this sentence (when read in isolation) 😉
Yes, in general I think that pointing the client into the right direction is helpful. Although a MOVED or REDIRECT response to EXEC is somewhat surprising, it is the clearest indication of what to do next, IMHO.
This depends on the abstraction the client offers. Looking at redis-py for example, watch seems to be part of the pipeline and there is even a convenience function |
Signed-off-by: zhaozhao.zz <[email protected]>
I don't think the documentation accounts for the "redirection" case, which is understandable since the Ignoring the fact that this is the current cluster behavior, I would still think returning I would also agree that, ideally, standalone should follow suit and align with the cluster's behavior. I am not sure if the standalone client has this concept of "topology refresh" and if not, even though the "MOVED" error could be confusing, it would still be treated as "abort" effectively; but if yes, "MOVED" would be a better error IMO. |
test "MULTI-EXEC with write operations is MOVED" {
$replica MULTI
catch {$replica HSET h b 4} err
assert {[string range $err 0 4] eq {MOVED}}
catch {$replica exec} err
assert {[string range $err 0 8] eq {EXECABORT}}
} @PingXie Do you think we should also modify the response for cluster to return p.s. actually, we originally returned |
Yes. That would be my preference (and the reason being it gives more chance to the client to update its view of the cluster topology). |
I vote for option 1. ✔️ The client will get a redirect either from one of the commands inside the transaction (instead of QUEUED) or from EXEC, so a smart client can figure this out. ✔️ EXEC consistently returns -EXECABORT if any command returned error instead of QUEUED. Redirects are errors in this sense. |
thanks for doing this pic, it look clear. i vote for the option 1, we keep the old cluster way and also make standlone to be the same way |
option 1 is my choice, Thanks @soloestoy |
It looks like we've reached a consensus chose option 1. @PingXie, if you don't object, I'll go ahead : ) Before make the changes, I think it's better to merge #961 first. If an error occurs within the transaction, we will clear the commands and only retain the flag. This way, both the cluster and standalone instances can directly allow the |
I still like option 2's experience but option 1 works for me too and I can see it being the safer option as it doesn't change the existing behavior on clusters. We should also update the documentation for both cluster and standalone after closing this PR. |
Option 1 also seems OK to me. |
Signed-off-by: zhaozhao.zz <[email protected]>
After #961, we don't need to modify any code to achieve option 1, we just need to add test cases : ) |
Signed-off-by: zhaozhao.zz <[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.
After #961, we don't need to modify any code to achieve option 1, we just need to add test cases : )
LGTM. so since we reset the mstate (actually is the cmd_flags), the exec can go directly to EXECABORT (it did not pass the CLIENT_CAPA_REDIRECT check), that is new to me.
Signed-off-by: zhaozhao.zz <[email protected]>
In standalone mode, when a `-REDIRECT` error occurs, special handling is required if the client is in the `MULTI` context. We have adopted the same handling method as the cluster mode: 1. If a command in the transaction encounters a `REDIRECT` at the time of queuing, the execution of `EXEC` will return an `EXECABORT` error (we expect the client to redirect and discard the transaction upon receiving a `REDIRECT`). That is: ``` MULTI ==> +OK SET x y ==> -REDIRECT EXEC ==> -EXECABORT ``` 2. If all commands are successfully queued (i.e., `QUEUED` results are received) but a redirect is detected during `EXEC` execution (such as a primary-replica switch), a `REDIRECT` is returned to instruct the client to perform a redirect. That is: ``` MULTI ==> +OK SET x y ==> +QUEUED failover EXEC ==> -REDIRECT ``` --------- Signed-off-by: zhaozhao.zz <[email protected]>
In standalone mode, when a `-REDIRECT` error occurs, special handling is required if the client is in the `MULTI` context. We have adopted the same handling method as the cluster mode: 1. If a command in the transaction encounters a `REDIRECT` at the time of queuing, the execution of `EXEC` will return an `EXECABORT` error (we expect the client to redirect and discard the transaction upon receiving a `REDIRECT`). That is: ``` MULTI ==> +OK SET x y ==> -REDIRECT EXEC ==> -EXECABORT ``` 2. If all commands are successfully queued (i.e., `QUEUED` results are received) but a redirect is detected during `EXEC` execution (such as a primary-replica switch), a `REDIRECT` is returned to instruct the client to perform a redirect. That is: ``` MULTI ==> +OK SET x y ==> +QUEUED failover EXEC ==> -REDIRECT ``` --------- Signed-off-by: zhaozhao.zz <[email protected]>
…#895) In standalone mode, when a `-REDIRECT` error occurs, special handling is required if the client is in the `MULTI` context. We have adopted the same handling method as the cluster mode: 1. If a command in the transaction encounters a `REDIRECT` at the time of queuing, the execution of `EXEC` will return an `EXECABORT` error (we expect the client to redirect and discard the transaction upon receiving a `REDIRECT`). That is: ``` MULTI ==> +OK SET x y ==> -REDIRECT EXEC ==> -EXECABORT ``` 2. If all commands are successfully queued (i.e., `QUEUED` results are received) but a redirect is detected during `EXEC` execution (such as a primary-replica switch), a `REDIRECT` is returned to instruct the client to perform a redirect. That is: ``` MULTI ==> +OK SET x y ==> +QUEUED failover EXEC ==> -REDIRECT ``` --------- Signed-off-by: zhaozhao.zz <[email protected]> Signed-off-by: Ping Xie <[email protected]>
…#895) In standalone mode, when a `-REDIRECT` error occurs, special handling is required if the client is in the `MULTI` context. We have adopted the same handling method as the cluster mode: 1. If a command in the transaction encounters a `REDIRECT` at the time of queuing, the execution of `EXEC` will return an `EXECABORT` error (we expect the client to redirect and discard the transaction upon receiving a `REDIRECT`). That is: ``` MULTI ==> +OK SET x y ==> -REDIRECT EXEC ==> -EXECABORT ``` 2. If all commands are successfully queued (i.e., `QUEUED` results are received) but a redirect is detected during `EXEC` execution (such as a primary-replica switch), a `REDIRECT` is returned to instruct the client to perform a redirect. That is: ``` MULTI ==> +OK SET x y ==> +QUEUED failover EXEC ==> -REDIRECT ``` --------- Signed-off-by: zhaozhao.zz <[email protected]> Signed-off-by: Ping Xie <[email protected]>
…#895) In standalone mode, when a `-REDIRECT` error occurs, special handling is required if the client is in the `MULTI` context. We have adopted the same handling method as the cluster mode: 1. If a command in the transaction encounters a `REDIRECT` at the time of queuing, the execution of `EXEC` will return an `EXECABORT` error (we expect the client to redirect and discard the transaction upon receiving a `REDIRECT`). That is: ``` MULTI ==> +OK SET x y ==> -REDIRECT EXEC ==> -EXECABORT ``` 2. If all commands are successfully queued (i.e., `QUEUED` results are received) but a redirect is detected during `EXEC` execution (such as a primary-replica switch), a `REDIRECT` is returned to instruct the client to perform a redirect. That is: ``` MULTI ==> +OK SET x y ==> +QUEUED failover EXEC ==> -REDIRECT ``` --------- Signed-off-by: zhaozhao.zz <[email protected]> Signed-off-by: Ping Xie <[email protected]>
doc for valkey-io/valkey#895 --------- Signed-off-by: zhaozhao.zz <[email protected]> Co-authored-by: Madelyn Olson <[email protected]>
In standalone mode, when a
-REDIRECT
error occurs, special handling is required if the client is in theMULTI
context.We have adopted the same handling method as the cluster mode:
If a command in the transaction encounters a
REDIRECT
at the time of queuing, the execution ofEXEC
will return anEXECABORT
error (we expect the client to redirect and discard the transaction upon receiving aREDIRECT
). That is:If all commands are successfully queued (i.e.,
QUEUED
results are received) but a redirect is detected duringEXEC
execution (such as a primary-replica switch), aREDIRECT
is returned to instruct the client to perform a redirect. That is: