-
Notifications
You must be signed in to change notification settings - Fork 171
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
feat: add AZ to replica info #721
Conversation
cluster.go
Outdated
primaryConn := c.connFn(primary, c.opt) | ||
conns[primary] = connrole{conn: primaryConn} | ||
if len(g.nodes) > 0 { | ||
g.nodes[0].AZ = primaryConn.AZ() |
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 think the AZ() is not yet available right after c.connFn
. c.connFn
only constructs the *mux
without making the actual TCP connection. We may need another way to do this.
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.
Oh, I just saw you implemented AZ() as m.pipe(0).AZ()
then it would make an actual connection to the server.
But here is still not a good place to call AZ(). It will be better if we call AZ() only when the AZ_AFFINITY is enabled and call it at
Line 265 in 09ad427
rIndex := c.opt.ReplicaSelector(uint16(i), g.nodes[1:]) |
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, you mean not always set AZ to ReplicaInfo
but if user want to know, then set AZ to ReplicaInfo
?
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 mean the AZ()
should be invoked only when necessary, which is when the AZ_AFFINITY is configured.
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.
And, the current calling point, which is right after result.parse
, is not a good place to call AZ()
. It will always create new connections. We should instead call it after:
Lines 232 to 243 in 09ad427
var removes []conn | |
c.mu.RLock() | |
for addr, cc := range c.conns { | |
if fresh, ok := conns[addr]; ok { | |
fresh.conn = cc.conn | |
conns[addr] = fresh | |
} else { | |
removes = append(removes, cc.conn) | |
} | |
} | |
c.mu.RUnlock() |
So that we can reuse existing connections as much as 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.
cluster.go
Outdated
@@ -259,6 +259,10 @@ func (c *clusterClient) _refresh() (err error) { | |||
} | |||
if len(g.nodes) > 1 { | |||
n := len(g.nodes) - 1 | |||
for i, replica := range g.nodes[1:] { | |||
rConn := conns[replica.Addr].conn | |||
g.nodes[i+1].AZ = rConn.AZ() |
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 the others look good to me. The only thing left is that AZ()
itself is too costly. Calling AZ()
sequentially could block the refresh
for a long time if all the rConn
haven't actually connected.
I think we should continue to complete the AZ_AFFINITY
feature in this PR so that we can skip AZ()
calls when it is not configured on the client. Parallelizing AZ()
calls can be another 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.
I'm perfectly wrong. How about this?
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, thanks a lot @proost!
previous discussion: #710