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
[2/5] cluster: refactor param passing & add params to the builder #670
[2/5] cluster: refactor param passing & add params to the builder #670
Conversation
493f776
to
ad326cb
Compare
e98553b
to
44af956
Compare
0c731a5
to
f9c3444
Compare
I want to review the major refactors again one last time but overall I think this looks great and simplifies a lot of the existing code. |
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 did a first round of review, which has made me grumpy. Many of these commits have too much going on at the same time to be easy to review, requiring me to scroll up and down to keep track of what's going on where. In some cases you have removed comments only to re-add them in a later commit, requiring me to keep track of those changes. Making commits one logical change at a time means that shouldn't happen.
Don't get me wrong, I like the direction here and I think the code is better off at the end, but as a reviewer getting there is much more painful than it should be if these commits were properly factored and better used the commit messages to explain the purpose of changes (although I noticed some attempts at doing this, which I appreciated).
redis/src/cluster.rs
Outdated
format!("rediss://{}/#insecure", host_port) | ||
} | ||
Some(TlsMode::Secure) => format!("rediss://{}", host_port), | ||
fn get_connection_addr(node: (String, u16), tls_insecure: Option<bool>) -> ConnectionAddr { |
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.
Please ditch the get_
prefix (see the API guidelines).
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 name do you suggest instead?
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.
Just use connection_addr()
? But alternatively, maybe this should be a constructor on ConnectionAddr
?
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.
The get_ prefix is used in too many places in the existing code base. I think it would be best to keep the name the same.
I've made it a function of ClusterParams as it doesn't make sense to create a constructor for ConnectionAddr which requires TlsMode which is only used by cluster.
@@ -27,7 +32,10 @@ impl ClusterClientBuilder { | |||
.into_iter() | |||
.map(|x| x.into_connection_info()) | |||
.collect(), | |||
cluster_params: ClusterParams::default(), | |||
cluster_params: ClusterParams { | |||
auto_reconnect: true, |
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 seems like an unrelated change?
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.
No, the default value of auto_reconnect should be true, not false.
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.
So it's a new option?
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.
No, but it is moved from ClusterConnection to ClusterParams.
@@ -145,7 +145,10 @@ impl ClusterClientBuilder { | |||
/// Sets the default timeout for all new connections (default is None). | |||
/// | |||
/// If the value is `None`, then `get_connection` call may block indefinitely. | |||
/// Passing Some(Duration::ZERO) to this method will result in an error. | |||
/// |
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.
These changes should be folded back into the commits that introduced them.
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.
Done
@@ -210,11 +210,12 @@ impl ClusterClientBuilder { | |||
self | |||
} | |||
|
|||
/// Sets the default auto reconnect parameter for all new connections (default is true). | |||
/// Disables auto reconnect for all new connections (default is enabled). |
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.
Please fold this into the preceding commit.
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.
Done
|
||
[slot_data.master().to_string(), replica] | ||
})?; | ||
*slots = self.create_new_slots()?; |
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.
Moving this code should be a separate commit from the other changes, to the extent possible.
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.
Done
.map(|slot_data| (slot_data.end(), get_addr(slot_data))) | ||
.collect(), | ||
); | ||
if let Ok(Value::Bulk(response)) = cmd.query(conn) { |
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.
Can this be a separate commit, too?
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.
Done
- move methods in order: constructor, pub fn, pub(crate) fn, fn - move connect fn inside impl & convert it to a method later on - move trait impl next to main impl - move map_cmds_to_nodes with related functions - remove duplicate check_connection
- use plain host:port node naming, even for TLS as the tls mode/insecure flag will always be the same for all connections
- create new Connection directly instead of creating a Client first - convert to methods & use required params from self instead of passing - set connections within create_initial_connections & call refresh_slots
… cluster related params - move get_connection_info & get_connection_addr to ClusterParams - move validate_duration logic to ClusterParams - remove unnecessary RefCell from params - this is to simplify passing multiple params to & inside the impl
f9c3444
to
4fe97ec
Compare
I've gone back through the PR, and I'm about ready to approve but have one more ask: Since you've done the noble work of making the slot parsing logic into a pure function, can we add some unit tests of that function? I think it would be very valuable to add test coverage there. |
I can add them, but I would like to get this PR merged first so you can review the next PR & the tests-related PR in parallel. |
I would feel a lot better about merging this if the code had unit tests. |
@@ -64,6 +64,12 @@ use crate::cluster_routing::{Routable, RoutingInfo, Slot, SLOT_SIZE}; | |||
|
|||
type SlotMap = BTreeMap<u16, [String; 2]>; | |||
|
|||
#[derive(Clone, Copy)] |
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 should stay above its impl
block. I guess I missed this the first time around?
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.
We've removed impl block for TlsMode.
Some(port) => format!("{}:{}", host, port), | ||
None => host.to_string(), | ||
}; | ||
fn get_connection_addr(node: (String, u16), tls_mode: Option<TlsMode>) -> ConnectionAddr { |
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.
If this commit is about TlsMode
, don't change the name and signature for this function as part of this commit.
redis/src/cluster.rs
Outdated
@@ -775,6 +737,17 @@ fn get_slots(connection: &mut Connection, tls_insecure: Option<bool>) -> RedisRe | |||
Ok(result) | |||
} | |||
|
|||
fn get_connection_info(node: &str, cluster_params: &ClusterParams) -> ConnectionInfo { |
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.
Okay, I'm sorry but this isn't working for me. Here you just add a new function that gets a &str
and starts to parse it with two unwrap()
calls without any clarity about how the invariants are upheld that these are actually Some
. I think the changes you are making are probably for the better, but you have so much stuff in flight at the same time that I'm unable to keep all the context around to do a review with the level of care that I'm used to.
At this point I don't want to review these many-commit PRs from you anymore. I would like one PR at a time, one commit per PR, and if the commit message has a bullet list in it you should split it up more.
Going to close this for now. Would be great if you can open a small PR to move forward on the refactoring. |
Currently, all the params in the
ClusterConnection
have individual fields in the struct, which makes it challenging to add new parameters to the client & also forces us to pass 3-4 params over & over (user/password/tls_insecure etc.). Also, there is no way to provide default values for the parameters that can be set on the connection level.With this PR, I've refactored the cluster connection to store & pass all the parameters using the
ClusterParams
struct added in the previous PR & also added functions to the builder to set default values for each.In addition, I've made the following changes:
build()
function in the cluster client builder & only use it when we need to create the connectionDepends on #669.