[JAVA-1944] Getting error when reading from secondary nodes with async driver Created: 31/Aug/15  Updated: 11/Sep/15  Resolved: 10/Sep/15

Status: Closed
Project: Java Driver
Component/s: Async
Affects Version/s: 3.0.3
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Jonas Mücke Assignee: Ross Lawley
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Ubuntu 14.04, Java 8, Vertx


Issue Links:
Duplicate
duplicates JAVA-1954 count/find query gives: MongoNotPrima... Closed

 Description   

When i use the async driver and connect to a replica set (3 nodes), i get most of the time (66%+) and error:

com.mongodb.MongoNotPrimaryException: The server is not the primary and did not execute the operation

final MongoClientSettings clientSettings = MongoClientSettings.builder()
        .codecRegistry(CodecRegistries.fromRegistries(
                CodecRegistries.fromProviders(asList(new ValueCodecProvider(), new DocumentCodecProvider(), new BsonValueCodecProvider())),
                new VertxCodecRegistry()
        ))
        .clusterSettings(ClusterSettings.builder()
                .hosts(Lists.newArrayList(new ServerAddress(host, port)))
                .build())
        .readPreference(ReadPreference.nearest())                
        .build();
 
mongoClient = MongoClients.create(clientSettings);
 
FindIterable<JsonObject> find = mongoDatabase.getCollection(collectionName)
        .find(BsonDocument.parse(matcher.encode()), JsonObject.class);
 
if (projection != null && !projection.isEmpty()) {
    find = find.projection(BsonDocument.parse(projection.encode()));
}
 
if (page != null && !page.isEmpty()) {
    find.limit(page.getInteger("limit", 10));
    find.skip(page.getInteger("offset", 0));
}
 
find.into(new ArrayList<>(), (List<JsonObject> elements, Throwable error) -> {
    if (error != null) {
        LOG.warning("Could not execute query: " + matcher);
        message.fail(500, error.getMessage());
    } else {
        message.reply(new JsonArray(elements));
    }
});

If i use the sync driver or change the read preferences to primary everthing works fine. I suppose it is a bug?



 Comments   
Comment by Githook User [ 11/Sep/15 ]

Author:

{u'username': u'rozza', u'name': u'Ross Lawley', u'email': u'ross.lawley@gmail.com'}

Message: Use the AsyncReadBinding's readPreference with the ReadConnectionSource

JAVA-1954 JAVA-1944
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/54e67fb5879c3a1017cd13d24b0b29f4d22a9e47

Comment by Githook User [ 11/Sep/15 ]

Author:

{u'username': u'rozza', u'name': u'Ross Lawley', u'email': u'ross.lawley@gmail.com'}

Message: Use the AsyncReadBinding's readPreference with the ReadConnectionSource

JAVA-1954 JAVA-1944
Branch: 3.0.x
https://github.com/mongodb/mongo-java-driver/commit/0b95a2f70b751523112bc27a2747f70f04a82c6e

Comment by Ross Lawley [ 10/Sep/15 ]

Marking this as a duplicate as the test code in JAVA-1954 helped identify the cause.

This will be fixed in 3.0.4 & 3.1

Comment by Jonas Mücke [ 09/Sep/15 ]

Hi Ross, sadly I didn't get time to look into it, but I will try to check it at the end of this week.

Comment by Ross Lawley [ 09/Sep/15 ]

Hi j_muecke, just chasing this up, did your checking find anything?

Comment by Jonas Mücke [ 01/Sep/15 ]

Thanks for your check. I will try to run your sample code on my machine. Maybe it is a vertx problem.

Comment by Jeffrey Yemin [ 31/Aug/15 ]

I tried to reproduce this with the following simplified program:

import com.mongodb.ReadPreference;
import com.mongodb.ServerAddress;
import com.mongodb.async.SingleResultCallback;
import com.mongodb.async.client.*;
import com.mongodb.connection.ClusterSettings;
import org.bson.Document;
 
import java.util.ArrayList;
import java.util.List;
 
import static java.util.Collections.singletonList;
 
public class JAVA1944 {
    public static void main(String[] args) throws InterruptedException {
        int port = 27017;
        MongoClientSettings clientSettings =
        MongoClientSettings.builder()
                           .clusterSettings(ClusterSettings.builder()
                                                           .hosts(singletonList(new
                                                                                ServerAddress("localhost", port)))
                                                           .build())
                           .readPreference(ReadPreference.nearest())
                           .build();
 
        MongoClient mongoClient = MongoClients.create(clientSettings);
 
        MongoDatabase mongoDatabase = mongoClient.getDatabase("test");
        MongoCollection<Document> collection = mongoDatabase.getCollection("JAVA1944");
 
 
        collection.find().into(new ArrayList<>(), new ListSingleResultCallback(collection));
 
        Thread.sleep(Long.MAX_VALUE);
    }
 
    private static class ListSingleResultCallback implements SingleResultCallback<List<Document>> {
        private final MongoCollection<Document> collection;
 
        public ListSingleResultCallback(final MongoCollection<Document> collection) {
            this.collection = collection;
        }
 
        @Override
        public void onResult(final List<Document> elements, final Throwable error) {
            if (error != null) {
                System.out.println(error.toString());
            }
            // try again
            collection.find().into(new ArrayList<>(), this);   
    }
}

I ran it three times against a three-server replica set, and changed the port to each of the three members. I didn't get any exceptions.

At this point I'm not sure what the difference in between our environments, so we will need to investigate this further.

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