-
Notifications
You must be signed in to change notification settings - Fork 186
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: send readonly command #430
Changes from 7 commits
7759b3a
92288cc
519cd72
0231a44
a2a1aa8
98040d7
f328c8f
ccd4a28
3ec3548
cd6a674
5702ce3
1375321
87e2b39
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -18,7 +18,6 @@ import ( | |||||
|
||||||
// ErrNoSlot indicates that there is no redis node owns the key slot. | ||||||
var ErrNoSlot = errors.New("the slot has no redis node") | ||||||
var ErrReplicaOnlyConflict = errors.New("ReplicaOnly conflicts with SendToReplicas option") | ||||||
|
||||||
type retry struct { | ||||||
cIndexes []int | ||||||
|
@@ -93,17 +92,13 @@ type connrole struct { | |||||
func newClusterClient(opt *ClientOption, connFn connFn) (client *clusterClient, err error) { | ||||||
client = &clusterClient{ | ||||||
cmd: cmds.NewBuilder(cmds.InitSlot), | ||||||
opt: opt, | ||||||
connFn: connFn, | ||||||
opt: opt, | ||||||
conns: make(map[string]connrole), | ||||||
retry: !opt.DisableRetry, | ||||||
aws: len(opt.InitAddress) == 1 && strings.Contains(opt.InitAddress[0], "amazonaws.com"), | ||||||
} | ||||||
|
||||||
if opt.ReplicaOnly && opt.SendToReplicas != nil { | ||||||
return nil, ErrReplicaOnlyConflict | ||||||
} | ||||||
|
||||||
client.connFn = func(dst string, opt *ClientOption) conn { | ||||||
cc := connFn(dst, opt) | ||||||
cc.SetOnCloseHook(func(err error) { | ||||||
|
@@ -225,7 +220,15 @@ func (c *clusterClient) _refresh() (err error) { | |||||
for master, g := range groups { | ||||||
conns[master] = connrole{conn: c.connFn(master, c.opt), replica: false} | ||||||
for _, addr := range g.nodes[1:] { | ||||||
conns[addr] = connrole{conn: c.connFn(addr, c.opt), replica: true} | ||||||
var cc conn | ||||||
if c.opt.ReplicaOnly { | ||||||
opt := *c.opt | ||||||
cc = c.connFn(addr, &opt) | ||||||
} else { | ||||||
cc = c.connFn(addr, c.opt) | ||||||
} | ||||||
|
||||||
conns[addr] = connrole{conn: cc, replica: true} | ||||||
} | ||||||
} | ||||||
// make sure InitAddress always be present | ||||||
|
@@ -241,7 +244,8 @@ func (c *clusterClient) _refresh() (err error) { | |||||
|
||||||
c.mu.RLock() | ||||||
for addr, cc := range c.conns { | ||||||
if fresh, ok := conns[addr]; ok { | ||||||
fresh, ok := conns[addr] | ||||||
if ok && cc.replica == fresh.replica { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can still reuse the conn if c.opt.SendToReplicas is not configured. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @proost, thank you very much! It looks great! |
||||||
conns[addr] = connrole{ | ||||||
conn: cc.conn, | ||||||
replica: fresh.replica, | ||||||
|
@@ -256,7 +260,7 @@ func (c *clusterClient) _refresh() (err error) { | |||||
var rslots []conn | ||||||
for master, g := range groups { | ||||||
switch { | ||||||
case c.opt.ReplicaOnly && len(g.nodes) > 1: | ||||||
case c.opt.SendToReplicas == nil && c.opt.ReplicaOnly && len(g.nodes) > 1: | ||||||
nodesCount := len(g.nodes) | ||||||
for _, slot := range g.slots { | ||||||
for i := slot[0]; i <= slot[1]; i++ { | ||||||
|
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 am still a little confused. So now, are we requiring users to set
ReplicaOnly
as well even if they useSendToReplicas
?I thought we would only set
ReplicaOnly
transparently for users here to theopt
.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.
fix it. 3ec3548
when
SendToReplicas
is configured andReplicaOnly
is true,when
SendToReplicas
is configured andReplicaOnly
is false,when
SendToReplicas
is not configured andReplicaOnly
is 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.
Why we don't send "READONLY" to replicas when SendToReplicas is configured and ReplicaOnly is false?
Isn't it the original issue you want to fix?
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.
cd6a674
Yes, it doesn't matter HOW. i just want to send "READONLY" command to replica connections automatically. but if you think read-only mode as a default is better than i changed it.