[JAVA-4477] MongoChangeStreamCursor tryNext() call blocks and waits indefinitely when there is a network connection loss Created: 07/Feb/22  Updated: 27/Oct/23  Resolved: 08/Feb/22

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

Type: Question Priority: Major - P3
Reporter: Ajay Mathias Assignee: Jeffrey Yemin
Resolution: Works as Designed Votes: 1
Labels: changestreams, external-user, trynext
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Text File AltasTryNextCallDump.txt    

 Description   

Summary

MongoChangeStreamCursor tryNext() call blocks and waits indefinitely when there is a network connection loss.

My code looks something like this:

MongoChangeStreamCursor<ChangeStreamDocument<Document>> cursor = collection.watch(pipeline).fullDocument(FullDocument.UPDATE_LOOKUP).cursor();
ChangeStreamDocument<Document> changeStreamDocument = cursor.tryNext();
{{if (changeStreamDocument != null) { }}
     // do something
}

The purpose of using the tryNext (instead of hasNext and next) is because of its non-blocking nature.
But in case of a network connection loss, the tryNext call blocks the thread and waits indefinitely without throwing any exception.

Although the MongoClient was created with these options i.e. &connectTimeoutMS=10000&serverSelectionTimeoutMS=10000, the tryNext call gets stuck even after surpassing the configured timeouts.

 

Expected behavior
tryNext method is expected to be a non blocking call.

An appropriate MongoException should have been thrown immediately or as soon as the waiting time crosses the configured timeout period.

Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

The driver version is mongo-java-driver version 3.12.10
But the issue could be reproduced in java driver version 3.11 also.

The database to which I have connected is Mongo DB Atlas.

How to Reproduce

Steps to reproduce. If possible, please include a Short, Self Contained, Correct (Compilable), Example.

Write a simple MongoChangeStream cursor program and call to its tryNext() method and simulate a network connection loss.

This use case can be easily tested by turning off the Wifi of the computer or the router.
The thread dump captured using JStack is also attached.

Additional Background

This use case can be easily tested by turning off the Wifi of the computer or the router.
The thread dump captured using JStack is also attached.
The database to which I have connected is Mongo DB Atlas. The driver version is mongo-java-driver version 3.12.10

The thread dump captured using JStack is also attached.



 Comments   
Comment by Jeffrey Yemin [ 08/Feb/22 ]

Glad to hear you got it working as you expected.

Comment by Ajay Mathias [ 08/Feb/22 ]

Update - Setting the serverSelectionTimeoutMS worked.

Thanks

Comment by Ajay Mathias [ 08/Feb/22 ]

Hi @Jeffrey Yemin

Many thanks. That worked.
I had set the socketTimeoutMS=10000 in the client, but the exception was thrown after 30 seconds.

{{Exception in thread "main" com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector

{readPreference=primary}

}}

Is there a way to override this and still throw the exception after 10 seconds even if the client is connected to the primary?

 

Comment by Jeffrey Yemin [ 07/Feb/22 ]

Hi ajay2589@gmail.com

Can you try again after adding socketTimeoutMS=10000 to the connection string? Socket timeout is what ensures that a socket read will time out, not connect timeout.

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