|
Author:
{'name': 'Valentin Kovalenko', 'email': 'valentin.kovalenko@mongodb.com', 'username': 'stIncMale'}
Message: JAVA-3928 Make `DefaultConnectionPool` pausable (#701)
Following are the details regarding the `createSessions` parameter in the constructor of `AbstractUnifiedTest`.
The parameter was introduced to work around a race condition in the test
`minPoolSize-error.json`: "Network error on minPoolSize background creation".
1) The test format according to
https://github.com/mongodb/specifications/tree/master/source/server-discovery-and-monitoring/tests#test-format
is specified in
https://github.com/mongodb/specifications/blob/master/source/transactions/tests/README.rst#test-format.
2) The aforementioned format specifies the following steps:
"9. Create a new MongoClient client ... Pass this test's clientOptions if present.
10. Call client.startSession twice to create ClientSession objects session0 and session1".
3) Once a mongo client is created, it starts a monitor, successfully executes `isMaster`
because the first 3 commands in the test are allowed to succeed (``"skip": 3`), and unpauses the pool.
4) The pool's background thread is notified about the fact that the pool is unpaused
and starts populating the pool because the test specifies ``"minPoolSize": 10`.
5) Concurrently with 4), the test runner tries to create `session0` and `session1` as per 2).
If the pool's background thread is lucky, it consumes one or both of the allowed success results
that are left (``"skip": 3`), and the test fails because it cannot create either one or both sessions.
I somewhat verified this scenario by introducing an artificial delay
either in the pool's background thread (right before it starts creating connections to populate the pool),
or in the test runner right before it creates sessions. Depending on where I put the delay,
I can either make the test regularly pass, or regularly fail by failing to create the sessions.
There is no way to eliminate this race condition in the test without introducing a handle to control the pool's
background thread and the server monitor outside of a client. However, my understanding is that many of our
integration tests are racy, and we reduce the probability of unwanted outcomes by introducing delays in tests.
In this specific case, we already have a delay for the monitor thread after its first `isMaster`
(`"heartbeatFrequencyMS": 10000`), and it seems like we need to have something like
`"maintenanceInitialDelayMS": 2000` for the pool's background thread.
With this option the test passes regularly, though it still obviously has a race condition.
Not all drivers implement a pool option similar to `maintenanceInitialDelayMS`,
so instead of changing the spec and forcing everyone to have one,
I changed the test runner so that it does not create `session0` and `session1` for SDAM tests,
which do not use these sessions anyway.
JAVA-3928
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/17b2f91fd1c6957a0da3457616f287fd08ad89d0
|