Skip to content

Ignore maxWaitTime when CSOT is enabled. #1744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

vbabanin
Copy link
Member

@vbabanin vbabanin self-assigned this Jun 19, 2025
@katcharov katcharov marked this pull request as ready for review June 19, 2025 15:06
@katcharov katcharov requested a review from a team as a code owner June 19, 2025 15:06
@katcharov katcharov requested review from nhachicha, a team and stIncMale and removed request for a team and nhachicha June 19, 2025 15:06
Comment on lines +43 to 47
* Implementations of this interface must be immutable.
*
* @see TimePoint
*/
public interface Timeout {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Is this change needed because of a change done in this PR, or is it simply something that you noticed and improved?
  • Shouldn't the same be documented for StartTime?

Copy link
Member Author

@vbabanin vbabanin Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wasn’t required by changes in this PR, just a small improvement I noticed while reviewing the Timeout code. I thought documenting immutability in the Javadoc would be useful for anyone double-checking this detail, without needing to examine the implementations.

I’ve also added the note for StartTime as you suggested.

@@ -208,7 +210,7 @@ public InternalConnection get(final OperationContext operationContext) {
@Override
public void getAsync(final OperationContext operationContext, final SingleResultCallback<InternalConnection> callback) {
StartTime checkoutStart = connectionCheckoutStarted(operationContext);
Timeout maxWaitTimeout = checkoutStart.timeoutAfterOrInfiniteIfNegative(settings.getMaxWaitTime(NANOSECONDS), NANOSECONDS);
Timeout maxWaitTimeout = operationContext.getTimeoutContext().startWaitQueueTimeout(checkoutStart);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxWaitTimeout is called waitQueueTimeout in the get method. They should have equal names, and given that we obtain them by calling startWaitQueueTimeout, the name waitQueueTimeout seems to be more suitable. If it's not, maybe we should rename the method also?

Copy link
Member Author

@vbabanin vbabanin Jun 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to maxWaitTimeout everywhere in DefaultConnectionPool, as that’s the prevailing naming convention in the codebase. There are still some discrepancies in the javadocs, but this naming keeps it consistent with most usages internally.

private PooledConnection getPooledConnection(final Timeout waitQueueTimeout, final StartTime startTime) throws MongoTimeoutException {
private PooledConnection getPooledConnection(final Timeout waitQueueTimeout,
final StartTime startTime,
final OperationContext operationContext) throws MongoTimeoutException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that this methods uses only operationContext.getTimeoutContext(), let's accept TimeoutContext instead of OperationContext? The same applies to the acquirePermitOrGetAvailableOpenedConnection method and the constructor of DefaultConnectionPool.Task.

Interestingly, createTimeoutException rightly accepts TimeoutContext, not OperationContext.

elapsedMs, serverId.getAddress()));
String errorMessage = format("Timed out after %d ms while waiting for a connection to server %s.",
elapsedMs, serverId.getAddress());
return timeoutContext.hasTimeoutMS() ? createMongoTimeoutException(errorMessage) : new MongoTimeoutException(errorMessage);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's extract the errorMessage variable to a place before the if block, initialize it in the if and the else blocks, and then do return timeoutContext.hasTimeoutMS() ? createMongoTimeoutException(errorMessage) : new MongoTimeoutException(errorMessage); as the last statement in the createTimeoutException method. This way we will avoid duplicating this last statement.

*/
@Test
@DisplayName("Should ignore waitQueueTimeoutMS when timeoutMS is set")
public void shouldUseWaitQueueTimeoutMSWhenTimeoutIsNotSet() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DisplayName does not match the name/behavior of the test.


// when
TimeoutTrackingConnectionGetter connectionGetter = new TimeoutTrackingConnectionGetter(provider, timeoutSettings);
new Thread(connectionGetter).start();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of starting a new thread and never making sure it terminates, let's use cachedExecutor, which is properly terminated in cleanup.

.getCollection(namespace.getCollectionName());

collectionHelper.runAdminCommand("{"
+ " configureFailPoint: \"failCommand\","
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have com.mongodb.client.FailPoint for creating fail points in a way that cleans them up. Let's use it here and in other new tests.

Copy link
Member Author

@vbabanin vbabanin Jun 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are cases where the failpoint must be configured after a specific command has executed (see, for example, commit transactions here). In that case, using the FailPoint class would require another nested try, which would make the test a bit harder to read. I do agree that using FailPoint in a try at the beginning of the test is more explicit and clear, which i assume the majority of use-cases do.

In current tests case, we could certainly use FailPoint to make it explicit and clear, but it would introduce inconsistency in this class and might raise questions of what to use for others adding new tests to this class.

Ideally, it would be beneficial if a FailPoint instance could be injected with an annotation before each test and cleaned up automatically, so that we could enable it at any point in the test as needed without try/catch via FailPoint.enable() method.

I suggest we address this in a separate ticket to unify the approach in this (and probably other test classes), and to consider automatically injected FailPoint.

What do you think?

+ " }"
+ "}");

ExecutorService executor = Executors.newSingleThreadExecutor();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's properly shut executor down, and wait for shutting down to complete. We may also do that in an @AfterEach method, whatever seems more appropriate. This suggestion applies to all new tests in this file.

try (MongoClient mongoClient = createMongoClient(getMongoClientSettingsBuilder()
.timeout(100, TimeUnit.MILLISECONDS)
.applyToConnectionPoolSettings(builder -> builder
.maxWaitTime(1, TimeUnit.MILLISECONDS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we set maxWaitTime here?

Copy link
Member Author

@vbabanin vbabanin Jun 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Even though it is ignored, we don't need it here. It was a leftover from coping settings from the test above. Removed.

vbabanin added 2 commits June 26, 2025 17:52
Add JavaDoc to StartTime.
Shutdown executor properly.
@vbabanin vbabanin requested a review from stIncMale June 27, 2025 01:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants