-
Type: Bug
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: 2.13.3
-
Component/s: Connection Management
-
None
Hello,
I've seen a following stack trace:
java.lang.IllegalStateException: open at org.bson.util.Assertions.isTrue(Assertions.java:36) at com.mongodb.DBPort.runCommand(DBPort.java:219) at com.mongodb.DBPort.ensureOpen(DBPort.java:319) at com.mongodb.DBPort.<init>(DBPort.java:113) at com.mongodb.DBPort.<init>(DBPort.java:95) at com.mongodb.DBPortFactory.create(DBPortFactory.java:28) at com.mongodb.PooledConnectionProvider$ConnectionItemFactory.create(PooledConnectionProvider.java:186) at com.mongodb.PooledConnectionProvider$ConnectionItemFactory.create(PooledConnectionProvider.java:183) at com.mongodb.ConcurrentPool.createNewAndReleasePermitIfFailure(ConcurrentPool.java:150) at com.mongodb.ConcurrentPool.get(ConcurrentPool.java:118) at com.mongodb.PooledConnectionProvider.get(PooledConnectionProvider.java:79) at com.mongodb.DefaultServer.getConnection(DefaultServer.java:61) at com.mongodb.BaseCluster$WrappedServer.getConnection(BaseCluster.java:254) ....
I could not reproduce it, however I found a potential problem in DBPort.java:
do { try { _socket = _options.socketFactory.createSocket(); _socket.connect( _addr.getSocketAddress() , _options.connectTimeout ); _socket.setTcpNoDelay( ! USE_NAGLE ); _socket.setKeepAlive( _options.socketKeepAlive ); _socket.setSoTimeout( _options.socketTimeout ); _in = new BufferedInputStream( _socket.getInputStream() ); _out = _socket.getOutputStream(); successfullyConnected = true; } catch ( IOException e ){ close(); if (!_options.autoConnectRetry || (provider != null && !provider.hasWorked())) throw e; long waitSoFar = System.currentTimeMillis() - start; if (waitSoFar >= maxAutoConnectRetryTime) throw e; if (sleepTime + waitSoFar > maxAutoConnectRetryTime) sleepTime = maxAutoConnectRetryTime - waitSoFar; _logger.log(Level.WARNING, "Exception connecting to " + serverAddress().getHost() + ": " + e + ". Total wait time so far is " + waitSoFar + " ms. Will retry after sleeping for " + sleepTime + " ms."); ThreadUtil.sleep(sleepTime); sleepTime *= 2; } } while (!successfullyConnected);
If the first run of the loop results in an IOException, the DBPort is closed which sets the closed flag to true. However, If a subsequent run succeeds the flag is never reset which can cause the above stacktrace.
Is it a bug or am I missing something?