[JAVA-3856] Database connection error is not notified or notified after server selection timeout. Created: 10/Oct/20  Updated: 22/Sep/21  Resolved: 20/Oct/20

Status: Closed
Project: Java Driver
Component/s: Cluster Management
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Andrew Kaplanov Assignee: Ross Lawley
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to DRIVERS-1030 Drivers should check out an implicit ... Closed

 Description   

I try to connect to not existing database.
Following code does not return error after 60 sec of running.

        MongoClient client = MongoClients.create();
        MongoDatabase db = client.getDatabase("test");
 
        CountDownLatch latch = new CountDownLatch(1);
        db.listCollectionNames().subscribe(new Subscriber<>() {
            @Override
            public void onSubscribe(final Subscription subscription) {
                System.out.println("onSubscribe is called");
                subscription.request(Long.MAX_VALUE);
            }
 
            @Override
            public void onNext(final String s) {
                System.out.println("onNext is called: " + s);
            }
 
            @Override
            public void onError(final Throwable throwable) {
                System.out.println("onError is called");
                throwable.printStackTrace();
                latch.countDown();
            }
 
            @Override
            public void onComplete() {
                System.out.println("Complete is called");
                latch.countDown();
            }
        });
 
        System.out.println("Waiting finished with " + latch.await(60, TimeUnit.SECONDS));

Further it prints on console:

.. Exception in monitor thread while connecting to server localhost:27017
org.mongodb.driver.cluster - No server chosen by ReadPreferenceServerSelector ... Waiting for 30000 ms before timing out
...
Wait finished with false

This means that onError() was not called.

When MongoClient is  created with serverSelectionTimeout option as below:

        MongoClient client = MongoClients.create(MongoClientSettings.builder()
                .applyToClusterSettings(builder -> builder.serverSelectionTimeout(1, TimeUnit.SECONDS))
                .build());

Execution result is:

onSubscribe is called
... org.mongodb.driver.cluster - Exception in monitor thread while connecting to server 127.0.0.1:2701 ...
... (after 1 sec) ...
onError is called
com.mongodb.MongoTimeoutException: Timed out after 1000 ms while waiting for a server ...
...
Wait finished with true

 

Both cases are unacceptable for me.

Database connection error should return immediately.



 Comments   
Comment by Andrew Kaplanov [ 12/Oct/20 ]

Hi Ross Lawley, thank you for reply.

I hope double connection cost will be fixed in new release. 

I didn't understand at first about server selection timeout, since repeated connection attempts are not shown in the log. I made a test to check the connection to the database that appeared, everything works as it should. 

The task can be closed, thanks. Excuse for troubling.

 

Comment by Ross Lawley [ 12/Oct/20 ]

Hi akaplanov@gmail.com,

Thanks for the ticket, if you extended the latch await it would timeout shortly after the 60 seconds.

It asks a good question, why does it take 60+ seconds when the server selection timeout is 30 seconds?

This is an issue with how implicit sessions are handled within the driver which essentially requires a connection to determine if sessions are supported and then a connection for the operation. DRIVERS-1030 will ensure that the current double connection cost is removed from all drivers.

Both cases are unacceptable for me.

Database connection error should return immediately.

The driver itself is backed by a connection pool and monitoring threads. Why does the driver not immediately return when a connection errors? This is because when working with distributed systems, network issues and server events can be expected. So the driver is designed to be as robust as possible. The common case for deployments are they are available, healthy and usable. All MongoDB drivers favor allowing operations to proceed as soon as possible in the common case, at the cost of surprising behavior in uncommon cases - such as network events, replicaset topology changes etc..

For more information please see the Server Discovery And Monitoring specification.

All the best,

Ross

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