-
Notifications
You must be signed in to change notification settings - Fork 103
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
Fix RoutingInfo consistency #743
Fix RoutingInfo consistency #743
Conversation
ea7a26f
to
67b77e1
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.
While the purpose of the PR is good, I think it is too bloated. There is a lot of code duplication in tests and proxy utilities, not to mention the last commit which doesn't really belong to this PR.
- Request deserialization code should be put into scylla-cql, as it belongs there and not in scylla-proxy. At least, I don't think that we need to duplicate the structure definitions.
- There is lots of code to be deduplicated or shortened in the tests that this PR adds,
- The last commit needs to go out and be resent separately. I don't see how it belongs here.
Please try to reduce the number of lines added by this PR. I don't believe we need a nearly 1000-line PR to fix an issue about some parameters not being propagated properly in a handful of functions.
9c377a8
to
d05bde9
Compare
d05bde9
to
49e6aeb
Compare
Condition::or( | ||
Condition::RequestOpcode(RequestOpcode::Execute), | ||
Condition::or( | ||
Condition::RequestOpcode(RequestOpcode::Batch), | ||
Condition::and( | ||
Condition::RequestOpcode(RequestOpcode::Query), | ||
Condition::BodyContainsCaseSensitive(Box::new( | ||
*b"INTO consistency_tests", | ||
)), | ||
), | ||
), | ||
), |
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.
It's so verbose...
Maybe we should consider implementing boolean operators for Condition
s (not in this PR).
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.
What do you mean by this? Short-circuiting operations, such as &&
or ||
, are not implementable in terms of traits, due to traits being unable to force short-circuiting.
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.
https://doc.rust-lang.org/std/ops/index.html
Note that the && and || operators are currently not supported for overloading. Due to their short circuiting nature, they require a different design from traits for other operators like BitAnd. Designs for them are under discussion.
Interesting, I didn't know that. Maybe we can consider using the &
and |
operators instead until they figure the logical ones out.
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.
I'm in favour of explicit methods in case of combining Condition
s. Idiomatic Rust doesn't switch to operator overloading, unlike C++.
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.
I'm in favour of explicit methods in case of combining
Condition
s.
If by methods you mean non-static methods here, then I'd argue that they are similarly awkward as calling them without self
.
Idiomatic Rust doesn't switch to operator overloading, unlike C++.
I don't think this is true. Operators are usually overloaded for mathematical objects such as bignums or vectors. In our case, you would construct a predicate, a boolean expression - boolean operator are a natural fit (well, we would need to use the bitwise equivalents but it would be close enough). I don't think it is a big abuse of the syntax.
Ultimately, I think we should just allow closure predicates that takes a context object which allows doing all those checks directly in the code (e.g. |ctx| match ctx.request_opcode() { ... }
). This would lead to much more natural syntax and greater flexibility.
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 is anyway out of this PR's scope. For now, let's stick to methods.
This will be used in proxy, to inspect request frames from the driver.
The generated error contained wrong value list count: it failed to include the number of value lists that were already paired with statements. As a bonus, a cleaner `count()` implementation was added to `BatchValuesIterator` trait, instead of using a dirty workaround.
66c6f95
to
99458a2
Compare
99458a2
to
2efa6da
Compare
The iterator is not an accurate choice: the Batch struct does not contain any iteration state, so a plain slice would be a better choice.
e64228c
to
6fc86b5
Compare
Before, only borrowed requests were allowed (for instance, Query contained the borrowed query contents as &str). For convenient deserialization and for test purposes, owned requests are preferred, so the definitions are made contain `Cow`s.
This will be used in some tests.
This is required for tests.
Introduces DeserializableRequest trait whose main goal is testing purposes.
One simply asserts that serialization composed with deserialization is identity. Another makes sure that unknown flags lead to frame rejection (as deserializing frame containing unknown flags will likely lead to misinterpretation of some unknown protocol extensions).
The mentioned trait essentially serves the purpose of serialization, so the change is justified. The name `Request` will be used for an umbrella enum containing various types of requests.
This enum provided unified interface over CQL requests, useful for testing. Now, it supports only Query, Execute and Batch (it panics if attempted to deserialize a different opcode) and provided getters for Consistency and SerialConsistency. In the future, it can be extended for further test checks.
One test checks for each [serial] possible consistency that the request frame indeed contains the specified [serial] consistency. Another test checks that RoutingInfo's consistencies match the specified ones. As the latter test confirmed the bug in Session regarding RoutingInfo, it is temporarily marked as ignored. The mark will be removed in the next commit, after the bug is fixed.
The test added in the previous commit proves that the routing info has wrong Consistency and SerialConsistency set. Therefore, Session::query_paged(), execute_paged() and batch() are all fixed to respect correct consistencies. The test's "ignore" mark is henceforth removed.
As access to the execution profile is anyway needed in the callers of `Session::run_query()` (in order to put correct Consistency and SerialConsistency into RoutingInfo), the acquired Arc<ExecutionProfileInner> is passed to `Session::run_query()` as another argument. This prevents duplication of Arc cloning.
There are three levels of consistency that are taken into account by the Session: default exec profile's, per-statement exec profile's and per-statement one. To avoid confusion, we should use naming that clearly distinguishes them. Therefore, ExecuteQueryContext's field is renamed from the vague `consistency` to `consistency_set_on_statement` (the one directly set), as it is exactly its semantics.
Apparently, routing info had wrong Consistency and SerialConsistency set in iterator, too.
6fc86b5
to
b1664a7
Compare
A bug has been found that put wrong
Consistency
andSerialConsistency
intoRoutingInfo
. In order to:the following is done:
Query
,Execute
andBatch
frames,RoutingInfo
forLoadBalancingPolicy
contains the specified consistencies,Session
, the affected methods are fixed,Session
to make fiddling with consistency clearer,Pre-review checklist
[ ] I have adjusted the documentation in./docs/source/
.[ ] I added appropriateFixes:
annotations to PR description.