-
Notifications
You must be signed in to change notification settings - Fork 16
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
Added management connections to be used with the periodic checks #56
Conversation
f8c92a1
to
2aa84ce
Compare
2aa84ce
to
ad7dc11
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.
initial comments.
This PR is too large to review effectively. Please remove unnecessary changes, and if possible split to PRs, if not possible split to commits.
@@ -11,18 +11,40 @@ type IdentifierType = ArcStr; | |||
|
|||
#[derive(Clone, Eq, PartialEq, Debug)] | |||
pub(crate) struct ClusterNode<Connection> { | |||
pub connection: Connection, | |||
pub ip: Option<IpAddr>, | |||
user_connection: Connection, |
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.
why did you decide to hide all of the fields?
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 so if we'll have a connection pool in the future for user/management connections we'll have less code change, so I kept the same line of get functions for IP too. do you prefer we'll directly access the variables?
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 don't see how this reduces the code change in such a situation.
do you prefer we'll directly access the variables?
Yes, empty getters are usually avoided, unless there's an intention for encapsulation.
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 don't see how this reduces the code change in such a situation.
now:
fn get_connection {
self.connection
}
later
fn get_connection {
if pool.empty() {}
else {
pool.get-connection()
}
or something like that.
but I can remove it for now
redis/src/cluster_async/mod.rs
Outdated
let requested_nodes = read_guard.random_connections(num_of_nodes_to_query); | ||
let requested_nodes = read_guard.random_connections( | ||
num_of_nodes_to_query, | ||
inner.cluster_params.management_connections_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.
so this means that refresh_slots
ALWAYS uses management connections, if they are enabled? even if it wasn't triggered by periodic check?
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.
yes, do you see any downside with it?
It solves the issue of blocking/pubsub connections
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 since you added no documentation or explanations to the PR, I'm trying to understand all of the changes and the reasons behind 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.
I'll need to think about this, and understand what's the ramifications.
redis/src/cluster_async/mod.rs
Outdated
let (mut conn, ip) = C::connect(info, socket_addr) | ||
.timeout(connection_timeout) | ||
.await??; | ||
let connection_timeout: futures_time::time::Duration = params.connection_timeout.into(); |
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.
why is the type definition needed?
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.
without it - "..type inside async fn
body must be known in this context"
ad7dc11
to
990425f
Compare
4fb8852
to
33f18da
Compare
why is |
33f18da
to
3cea586
Compare
and re: the benchmarks - the 100 bytes results are pretty bad. Is that the average of multiple runs? |
@nihohit Updated benchmark results |
Those are averages of multiple runs? I'm trying to understand how robust is the 7% difference in one scenario. It's generally preferable to benchmark with Node, since the higher TPS mean that there's less overhead to mask/compensate for small effects, and the benchmarks conclude faster, which allows first more iterations. |
what's the 60_sec / 120_sec difference in the benchmarks? |
@nihohit Node benchmark results: <style> </style>
|
@nihohit |
951617c
to
5a3e7b0
Compare
@nihohit round |
c4d680e
to
0fc47c5
Compare
@shachlanAmazon round |
fe1237c
to
42dffe6
Compare
@shachlanAmazon Lets have a code walkthrough on Sunday and i'll go through the latest changes I did. Benchmarks are in progress |
42dffe6
to
d626d19
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.
The main issue I have is that you've added a lot of logic & branching, and the vast majority of it isn't tested. I'm not sure that it's possible to test this using the existing cluster testing infra structure - maybe the connection management logic should be spun off to a separate file / module, and tested separately?
@shachlanAmazon Benchmark results in rust show decrease in up to ~5%. I'm not sure why these changes affect the happy path, I also tested mainline with periodic checks without the addition of management connections and I haven't seen this degradation. I'll add benchmark results of this branch without periodic checks and mainline with periodic checks, and node benchmark results.
|
… to the user connection if needed
7f80d5b
to
d31c834
Compare
65f67ce
to
edec2e8
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.
round.
absolutely great work on the tests. well done!
AsyncClusterNode::new(user_conn, management_conn, ip) | ||
} | ||
|
||
pub(crate) async fn connect_and_check_all_connections<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.
all_connections -> both_connections
Initially I thought this is about running all connections in a cluster.
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.
changed to connect_and_check_all_node_connections
conn_utils.returned_ip_type = ConnectionIPReturnType::Specified(ip); | ||
drop(write_lock); | ||
runtime.block_on(async { | ||
let node: RedisResult<AsyncClusterNode<MockConnection>> = connect_and_check( |
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.
minor: use type alias instead of repeating this long declaration throughout.
None, | ||
) | ||
.await; | ||
assert!(node.is_ok() && node.unwrap().management_connection.is_none()); |
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.
throughout the tests - can we use MockConnection::id (or some other tool) to know which connection was chosen?
.get_mut(name) | ||
.unwrap_or_else(|| panic!("MockConnectionUtils for `{name}` were not installed")); | ||
conn_utils.return_connection_err = ShouldReturnConnectionError::Yes; | ||
let conn_type: RefreshConnectionType = RefreshConnectionType::AllConnections; |
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.
minor: why do you need the type declaration?
.await; | ||
assert!(node.is_err()); | ||
let err = node.unwrap_err(); | ||
assert!(err |
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.
minor: please also assert on err.kind(), throughout
f0adab3
to
877e5f2
Compare
@barshaul do you want to keep this open? |
This PR adds another connection (called 'management connection') for each cluster node so they could be used in the periodic checks, if the periodic checks is enabled.
Rebased over #64 , #90
Benchmark results:
<style> </style>