[JAVA-4289] Change stream cursors should be resilient to replicaset changes Created: 29/Mar/21  Updated: 28/Oct/23  Resolved: 14/Oct/21

Status: Closed
Project: Java Driver
Component/s: Change Streams
Affects Version/s: None
Fix Version/s: 4.4.0

Type: Bug Priority: Major - P3
Reporter: Ross Lawley Assignee: Jeffrey Yemin
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File drivers-1805.py    
Issue Links:
Related
is related to CSHARP-3963 MongoConnectionPoolPausedException sh... Closed
is related to KAFKA-212 Closing cursor exception Closed

 Description   

When running a change stream cursor it should be resilient to replicaset changes. 

Reproducing the error:

1. Create a change stream cursor

        MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017,localhost:27018,localhost:27019/?readPreference=secondary");
        // Select the MongoDB database.
        MongoDatabase database = mongoClient.getDatabase("testChangeStreams");
        database.drop();
        sleep();
 
        // Select the collection to query.
        MongoCollection<Document> collection = database.getCollection("documents");
 
        /*
         * Example 1
         * Create a simple change stream against an existing collection.
         */
        System.out.println("1. Initial document from the Change Stream:");
 
        // Create the change stream cursor.
        MongoChangeStreamCursor<ChangeStreamDocument<Document>> cursor = collection.watch().cursor();
 
        // Insert a test document into the collection.
        collection.insertOne(Document.parse("{username: 'alice123', name: 'Alice'}"));
        ChangeStreamDocument<Document> next = cursor.next();
        System.out.println(next);
 
        next = cursor.tryNext();
        while (next == null) {
            sleep();
            cursor.tryNext();
        }

Then hide the secondary node the cursor is using eg:

cfg = rs.conf()
cfg.members[1].priority = 0
cfg.members[1].hidden = true
rs.reconfig(cfg)

Produces this error:

Caused by: java.lang.IllegalStateException: state should be: open
	at com.mongodb.assertions.Assertions.isTrue(Assertions.java:79)
	at com.mongodb.internal.connection.DefaultServer.getConnection(DefaultServer.java:94)
	at com.mongodb.internal.binding.ClusterBinding$ClusterBindingConnectionSource.getConnection(ClusterBinding.java:141)
	at com.mongodb.client.internal.ClientSessionBinding$SessionBindingConnectionSource.getConnection(ClientSessionBinding.java:148)
	at com.mongodb.internal.operation.QueryBatchCursor.getMore(QueryBatchCursor.java:264)
	at com.mongodb.internal.operation.QueryBatchCursor.tryHasNext(QueryBatchCursor.java:219)
	at com.mongodb.internal.operation.QueryBatchCursor.tryNext(QueryBatchCursor.java:203)
	at com.mongodb.internal.operation.ChangeStreamBatchCursor$3.apply(ChangeStreamBatchCursor.java:96)
	at com.mongodb.internal.operation.ChangeStreamBatchCursor$3.apply(ChangeStreamBatchCursor.java:92)
	at com.mongodb.internal.operation.ChangeStreamBatchCursor.resumeableOperation(ChangeStreamBatchCursor.java:182)

Expected/desired result: the change stream should resume on a different secondary.

This may impact tailable cursors as well.

Note: When using a primary read preference, the change stream is resilient to topology changes.



 Comments   
Comment by Jeffrey Yemin [ 14/Oct/21 ]

Does not cherrypick cleanly to 4.3.x branch, so no longer plan to backport

Comment by Githook User [ 14/Oct/21 ]

Author:

{'name': 'Jeff Yemin', 'email': 'jeff.yemin@mongodb.com', 'username': 'jyemin'}

Message: Resume change stream on any MongoClientException (#800)

In order to handle the reported scenario, several changes are made:

1. DefaultConnectionPool throws a MongoServerUnavailableException if the pool is closed
2. DefaultServer throws a MongoServerUnavailableException if the server is closed
3. ChangeStreamBatchCursorHelper.isResumableError returns true for any MongoClientException
(MongoServerUnavailableException is a subclass of MongoClientException)

JAVA-4289
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/2352cff90e833da42018e788afda645547d57fd2

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