@@ -304,6 +304,11 @@ const (
304304// false: Initiate the connection without TLS/SSL.
305305// The default value is false.
306306//
307+ // maxStalenessSeconds=<seconds>
308+ //
309+ // specify a maximum replication lag, or “staleness” in seconds, for reads from secondaries, minimum value allowed is 90.
310+ // Works on MongoDB 3.4+
311+ //
307312// Relevant documentation:
308313//
309314// http://docs.mongodb.org/manual/reference/connection-string/
@@ -353,6 +358,7 @@ func ParseURL(url string) (*DialInfo, error) {
353358 var readPreferenceTagSets []bson.D
354359 minPoolSize := 0
355360 maxIdleTimeMS := 0
361+ maxStalenessSeconds := 0
356362 safe := Safe {}
357363 for _ , opt := range uinfo .options {
358364 switch opt .key {
@@ -390,6 +396,17 @@ func ParseURL(url string) (*DialInfo, error) {
390396 if err != nil {
391397 return nil , errors .New ("bad value for maxPoolSize: " + opt .value )
392398 }
399+ case "maxStalenessSeconds" :
400+ maxStalenessSeconds , err = strconv .Atoi (opt .value )
401+
402+ if err != nil {
403+ return nil , errors .New ("bad value for maxStalenessSeconds: " + opt .value )
404+ }
405+
406+ if maxStalenessSeconds > 0 && maxStalenessSeconds < 90 {
407+ return nil , errors .New ("maxStalenessSeconds too low " + opt .value + ", must be >= 90 seconds" )
408+ }
409+
393410 case "appName" :
394411 if len (opt .value ) > 128 {
395412 return nil , errors .New ("appName too long, must be < 128 bytes: " + opt .value )
@@ -455,6 +472,10 @@ func ParseURL(url string) (*DialInfo, error) {
455472 return nil , errors .New ("readPreferenceTagSet may not be specified when readPreference is primary" )
456473 }
457474
475+ if readPreferenceMode == Primary && maxStalenessSeconds > 0 {
476+ return nil , errors .New ("maxStalenessSeconds may not be specified when readPreference is primary" )
477+ }
478+
458479 info := DialInfo {
459480 Addrs : uinfo .addrs ,
460481 Direct : direct ,
@@ -469,6 +490,8 @@ func ParseURL(url string) (*DialInfo, error) {
469490 ReadPreference : & ReadPreference {
470491 Mode : readPreferenceMode ,
471492 TagSets : readPreferenceTagSets ,
493+
494+ MaxStalenessSeconds : maxStalenessSeconds ,
472495 },
473496 Safe : safe ,
474497 ReplicaSetName : setName ,
@@ -607,6 +630,8 @@ func (i *DialInfo) Copy() *DialInfo {
607630 if i .ReadPreference != nil {
608631 readPreference = & ReadPreference {
609632 Mode : i .ReadPreference .Mode ,
633+
634+ MaxStalenessSeconds : i .ReadPreference .MaxStalenessSeconds ,
610635 }
611636 readPreference .TagSets = make ([]bson.D , len (i .ReadPreference .TagSets ))
612637 copy (readPreference .TagSets , i .ReadPreference .TagSets )
@@ -679,6 +704,9 @@ type ReadPreference struct {
679704 // Mode determines the consistency of results. See Session.SetMode.
680705 Mode Mode
681706
707+ // MaxStalenessSeconds specify a maximum replication lag, or “staleness” in seconds, for reads from secondaries.
708+ MaxStalenessSeconds int
709+
682710 // TagSets indicates which servers are allowed to be used. See Session.SelectServers.
683711 TagSets []bson.D
684712}
@@ -768,6 +796,7 @@ func DialWithInfo(dialInfo *DialInfo) (*Session, error) {
768796 if info .ReadPreference != nil {
769797 session .SelectServers (info .ReadPreference .TagSets ... )
770798 session .SetMode (info .ReadPreference .Mode , true )
799+ session .SetMaxStalenessSeconds (info .ReadPreference .MaxStalenessSeconds )
771800 } else {
772801 session .SetMode (Strong , true )
773802 }
@@ -2190,6 +2219,24 @@ func (s *Session) SetPoolTimeout(timeout time.Duration) {
21902219 s .m .Unlock ()
21912220}
21922221
2222+ // SetMaxStalenessSeconds set the maximum of seconds of replication lag from secondaries
2223+ // You must specify a maxStalenessSeconds value of 90 seconds or longer: specifying a smaller maxStalenessSeconds value will raise an error.
2224+ // Works on MongoDB 3.4+
2225+ //
2226+ // Relevant documentation:
2227+ //
2228+ // https://docs.mongodb.com/manual/core/read-preference/#maxstalenessseconds
2229+ //
2230+ func (s * Session ) SetMaxStalenessSeconds (seconds int ) error {
2231+ s .m .Lock ()
2232+ defer s .m .Unlock ()
2233+ if seconds > 0 && seconds < 90 {
2234+ return errors .New ("SetMaxStalenessSeconds: minimum of seconds is 90" )
2235+ }
2236+ s .queryConfig .op .maxStalenessSeconds = seconds
2237+ return nil
2238+ }
2239+
21932240// SetBypassValidation sets whether the server should bypass the registered
21942241// validation expressions executed when documents are inserted or modified,
21952242// in the interest of preserving invariants in the collection being modified.
0 commit comments