[GODRIVER-2551] The request may be sent to the secodary node, although primaryPreferred is specified. Created: 19/Sep/22  Updated: 27/Oct/23  Resolved: 27/Sep/22

Status: Closed
Project: Go Driver
Component/s: None
Affects Version/s: 1.10.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Chao Yin Assignee: Kevin Albertson
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I found that although the primaryPreferred is specified, a small number of request will still be sent to the secondary node, even though the primary node is available at the time. 

mongo-go-driver: v1.10.2  

mongodb: 4.0 replicaset

```
var url = flag.String("url", "127.0.0.1:27031", "mongodb url")
 
func main() {
        flag.Parse()
 
        f := func() error {
                clientOptions := options.Client().ApplyURI(*url).SetReadPreference(readpref.PrimaryPreferred())
 
                client, err := mongo.NewClient(clientOptions)
                if err != nil

{                         return fmt.Errorf("new client failed:%v", err)                 }

 
                if err = client.Connect(context.Background()); err != nil

{                         return fmt.Errorf("connect failed: %v", err)                 }

                defer client.Disconnect(context.Background())
               
               /*
                if err = client.Ping(context.Background(), readpref.Primary()); err != nil

{                         fmt.Println("ping failed:", err)                 }

else

{                         fmt.Println("ping...")                 }

                */
 
                coll := client.Database("mydb").Collection("coll")
 
                filter := bson.D{{Key: "_id", Value: "test_val_readpref"}}
                res := coll.FindOne(context.Background(), filter)
                if res.Err() != nil

{                         fmt.Println("err:", res.Err())                         return res.Err()                 }

 
                return nil
        }
 
        for i := 0; i < 1000; i++ {
                if err := f(); err != nil

{                         fmt.Println("err ", err)                 }

else

{                         fmt.Println("success")                 }

        }
}
```

I have to ping the primary node before sending the request to make sure I got data from the primary. 

From the documentation here: https://www.mongodb.com/docs/v5.0/core/read-preference-use-cases/ 

The description of primaryPreferred is that

```

operations read from the primary but if it is unavailable, operations read from secondary members in most situations.

```

When the primary node is available and should all operations read from primary members?

 



 Comments   
Comment by Kevin Albertson [ 27/Sep/22 ]

a small number of request will still be sent to the secondary node, even though the primary node is available at the time.

That is likely expected behavior when a MongoClient has not checked all servers in the replica set.

The driver maintains a description of servers. A primaryPreferred read preference will select a secondary if the description of servers does not include a primary, but includes a secondary.

When the MongoClient is initially connected, it is only aware of the server "127.0.0.1:27031". After checking that server, the driver will discover other servers in the replica set.

From the documentation here: https://www.mongodb.com/docs/v5.0/core/read-preference-use-cases/

The description of primaryPreferred is that

```

operations read from the primary but if it is unavailable, operations read from secondary members in most situations.

"unavailable" means that the primary is not available to be selected by the driver. That does not suggest the primary server is not responding. The primary may not have yet been discovered.

Generated at Thu Feb 08 08:38:53 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.