-
Notifications
You must be signed in to change notification settings - Fork 230
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
Add support to MaxStalenessSeconds in ReadPreference #271
base: development
Are you sure you want to change the base?
Changes from 2 commits
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 |
---|---|---|
|
@@ -304,6 +304,11 @@ const ( | |
// false: Initiate the connection without TLS/SSL. | ||
// The default value is false. | ||
// | ||
// maxStalenessSeconds=<seconds> | ||
// | ||
// specify a maximum replication lag, or “staleness” in seconds, for reads from secondaries, minimum value allowed is 90. | ||
// Works on MongoDB 3.4+ | ||
// | ||
// Relevant documentation: | ||
// | ||
// http://docs.mongodb.org/manual/reference/connection-string/ | ||
|
@@ -353,6 +358,7 @@ func ParseURL(url string) (*DialInfo, error) { | |
var readPreferenceTagSets []bson.D | ||
minPoolSize := 0 | ||
maxIdleTimeMS := 0 | ||
maxStalenessSeconds := 0 | ||
safe := Safe{} | ||
for _, opt := range uinfo.options { | ||
switch opt.key { | ||
|
@@ -390,6 +396,17 @@ func ParseURL(url string) (*DialInfo, error) { | |
if err != nil { | ||
return nil, errors.New("bad value for maxPoolSize: " + opt.value) | ||
} | ||
case "maxStalenessSeconds": | ||
maxStalenessSeconds, err = strconv.Atoi(opt.value) | ||
|
||
if err != nil { | ||
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. I think this would need the 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. thanks @domodwyer, I've added you recommendation. |
||
return nil, errors.New("bad value for maxStalenessSeconds: " + opt.value) | ||
} | ||
|
||
if maxStalenessSeconds > 0 && maxStalenessSeconds < 90 { | ||
return nil, errors.New("maxStalenessSeconds too low " + opt.value + ", must be >= 90 seconds") | ||
} | ||
|
||
case "appName": | ||
if len(opt.value) > 128 { | ||
return nil, errors.New("appName too long, must be < 128 bytes: " + opt.value) | ||
|
@@ -455,6 +472,10 @@ func ParseURL(url string) (*DialInfo, error) { | |
return nil, errors.New("readPreferenceTagSet may not be specified when readPreference is primary") | ||
} | ||
|
||
if readPreferenceMode == Primary && maxStalenessSeconds > 0 { | ||
return nil, errors.New("maxStalenessSeconds may not be specified when readPreference is primary") | ||
} | ||
|
||
info := DialInfo{ | ||
Addrs: uinfo.addrs, | ||
Direct: direct, | ||
|
@@ -469,6 +490,8 @@ func ParseURL(url string) (*DialInfo, error) { | |
ReadPreference: &ReadPreference{ | ||
Mode: readPreferenceMode, | ||
TagSets: readPreferenceTagSets, | ||
|
||
MaxStalenessSeconds: maxStalenessSeconds, | ||
}, | ||
Safe: safe, | ||
ReplicaSetName: setName, | ||
|
@@ -607,6 +630,8 @@ func (i *DialInfo) Copy() *DialInfo { | |
if i.ReadPreference != nil { | ||
readPreference = &ReadPreference{ | ||
Mode: i.ReadPreference.Mode, | ||
|
||
MaxStalenessSeconds: i.ReadPreference.MaxStalenessSeconds, | ||
} | ||
readPreference.TagSets = make([]bson.D, len(i.ReadPreference.TagSets)) | ||
copy(readPreference.TagSets, i.ReadPreference.TagSets) | ||
|
@@ -679,6 +704,9 @@ type ReadPreference struct { | |
// Mode determines the consistency of results. See Session.SetMode. | ||
Mode Mode | ||
|
||
// MaxStalenessSeconds specify a maximum replication lag, or “staleness” in seconds, for reads from secondaries. | ||
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. Could you please add a comment stating that this option is supported in mongo >= 3.4 only ? |
||
MaxStalenessSeconds int | ||
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. Is this missing an 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 @domodwyer, the wire information is sent by socket.go(line: 131), I suppose that tag is not necessary here, thanks. |
||
|
||
// TagSets indicates which servers are allowed to be used. See Session.SelectServers. | ||
TagSets []bson.D | ||
} | ||
|
@@ -768,6 +796,7 @@ func DialWithInfo(dialInfo *DialInfo) (*Session, error) { | |
if info.ReadPreference != nil { | ||
session.SelectServers(info.ReadPreference.TagSets...) | ||
session.SetMode(info.ReadPreference.Mode, true) | ||
session.SetMaxStalenessSeconds(info.ReadPreference.MaxStalenessSeconds) | ||
} else { | ||
session.SetMode(Strong, true) | ||
} | ||
|
@@ -2190,6 +2219,24 @@ func (s *Session) SetPoolTimeout(timeout time.Duration) { | |
s.m.Unlock() | ||
} | ||
|
||
// SetMaxStalenessSeconds set the maximum of seconds of replication lag from secondaries | ||
// You must specify a maxStalenessSeconds value of 90 seconds or longer: specifying a smaller maxStalenessSeconds value will raise an error. | ||
// Works on MongoDB 3.4+ | ||
// | ||
// Relevant documentation: | ||
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. It might be worth including that if
|
||
// | ||
// https://docs.mongodb.com/manual/core/read-preference/#maxstalenessseconds | ||
// | ||
func (s *Session) SetMaxStalenessSeconds(seconds int) error { | ||
s.m.Lock() | ||
wpjunior marked this conversation as resolved.
Show resolved
Hide resolved
|
||
defer s.m.Unlock() | ||
if seconds > 0 && seconds < 90 { | ||
return errors.New("SetMaxStalenessSeconds: minimum of seconds is 90") | ||
} | ||
s.queryConfig.op.maxStalenessSeconds = seconds | ||
return nil | ||
} | ||
|
||
// SetBypassValidation sets whether the server should bypass the registered | ||
// validation expressions executed when documents are inserted or modified, | ||
// in the interest of preserving invariants in the collection being modified. | ||
|
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.
According to the documentation maxStalenessSeconds is not compatible with mode primary, so maybe you could add that restriction to the existing check below (line 460).
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.
Also, could you please add description of this parameter to the Dial method documentation (i.e. https://godoc.org/github.com/globalsign/mgo#Dial)
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.
thanks @eminano and @szank, could you see my commits updates ?, I committed some changes.