Skip to content

Commit cd9a45f

Browse files
authored
Prestart connection pool async work manager when running wait-queue-timeout.json, wait-queue-timeouts.json (#804)
JAVA-4318
1 parent b56ee8d commit cd9a45f

File tree

17 files changed

+213
-49
lines changed

17 files changed

+213
-49
lines changed

driver-core/src/main/com/mongodb/connection/ConnectionPoolSettings.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -398,15 +398,15 @@ public int hashCode() {
398398
@Override
399399
public String toString() {
400400
return "ConnectionPoolSettings{"
401-
+ "maxSize=" + maxSize
402-
+ ", minSize=" + minSize
403-
+ ", maxWaitTimeMS=" + maxWaitTimeMS
404-
+ ", maxConnectionLifeTimeMS=" + maxConnectionLifeTimeMS
405-
+ ", maxConnectionIdleTimeMS=" + maxConnectionIdleTimeMS
406-
+ ", maintenanceInitialDelayMS=" + maintenanceInitialDelayMS
407-
+ ", maintenanceFrequencyMS=" + maintenanceFrequencyMS
408-
+ ", connectionPoolListeners=" + connectionPoolListeners
409-
+ '}';
401+
+ "maxSize=" + maxSize
402+
+ ", minSize=" + minSize
403+
+ ", maxWaitTimeMS=" + maxWaitTimeMS
404+
+ ", maxConnectionLifeTimeMS=" + maxConnectionLifeTimeMS
405+
+ ", maxConnectionIdleTimeMS=" + maxConnectionIdleTimeMS
406+
+ ", maintenanceInitialDelayMS=" + maintenanceInitialDelayMS
407+
+ ", maintenanceFrequencyMS=" + maintenanceFrequencyMS
408+
+ ", connectionPoolListeners=" + connectionPoolListeners
409+
+ '}';
410410
}
411411

412412
ConnectionPoolSettings(final Builder builder) {

driver-core/src/main/com/mongodb/internal/connection/DefaultClusterFactory.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public final class DefaultClusterFactory {
4444
* @param clusterSettings the cluster settings
4545
* @param serverSettings the server settings
4646
* @param connectionPoolSettings the connection pool settings
47+
* @param internalConnectionPoolSettings the internal connection pool settings
4748
* @param streamFactory the stream factory
4849
* @param heartbeatStreamFactory the heartbeat stream factory
4950
* @param credential the credential, which may be null
@@ -57,8 +58,10 @@ public final class DefaultClusterFactory {
5758
* @since 3.6
5859
*/
5960
public Cluster createCluster(final ClusterSettings clusterSettings, final ServerSettings serverSettings,
60-
final ConnectionPoolSettings connectionPoolSettings, final StreamFactory streamFactory,
61-
final StreamFactory heartbeatStreamFactory, final @Nullable MongoCredential credential,
61+
final ConnectionPoolSettings connectionPoolSettings,
62+
final InternalConnectionPoolSettings internalConnectionPoolSettings,
63+
final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory,
64+
final @Nullable MongoCredential credential,
6265
final CommandListener commandListener, final String applicationName,
6366
final MongoDriverInformation mongoDriverInformation,
6467
final List<MongoCompressor> compressorList, final @Nullable ServerApi serverApi) {
@@ -69,13 +72,14 @@ public Cluster createCluster(final ClusterSettings clusterSettings, final Server
6972

7073
if (clusterSettings.getMode() == ClusterConnectionMode.LOAD_BALANCED) {
7174
ClusterableServerFactory serverFactory = new LoadBalancedClusterableServerFactory(clusterId, serverSettings,
72-
connectionPoolSettings, streamFactory, credential, commandListener, applicationName,
75+
connectionPoolSettings, internalConnectionPoolSettings, streamFactory, credential, commandListener, applicationName,
7376
mongoDriverInformation != null ? mongoDriverInformation : MongoDriverInformation.builder().build(), compressorList,
7477
serverApi);
7578
return new LoadBalancedCluster(clusterId, clusterSettings, serverFactory, dnsSrvRecordMonitorFactory);
7679
} else {
7780
ClusterableServerFactory serverFactory = new DefaultClusterableServerFactory(clusterId, clusterSettings, serverSettings,
78-
connectionPoolSettings, streamFactory, heartbeatStreamFactory, credential, commandListener, applicationName,
81+
connectionPoolSettings, internalConnectionPoolSettings,
82+
streamFactory, heartbeatStreamFactory, credential, commandListener, applicationName,
7983
mongoDriverInformation != null ? mongoDriverInformation : MongoDriverInformation.builder().build(), compressorList,
8084
serverApi);
8185

driver-core/src/main/com/mongodb/internal/connection/DefaultClusterableServerFactory.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class DefaultClusterableServerFactory implements ClusterableServerFactory
4141
private final ClusterSettings clusterSettings;
4242
private final ServerSettings serverSettings;
4343
private final ConnectionPoolSettings connectionPoolSettings;
44+
private final InternalConnectionPoolSettings internalConnectionPoolSettings;
4445
private final StreamFactory streamFactory;
4546
private final MongoCredentialWithCache credential;
4647
private final StreamFactory heartbeatStreamFactory;
@@ -52,15 +53,17 @@ public class DefaultClusterableServerFactory implements ClusterableServerFactory
5253
private final ServerApi serverApi;
5354

5455
public DefaultClusterableServerFactory(final ClusterId clusterId, final ClusterSettings clusterSettings,
55-
final ServerSettings serverSettings, final ConnectionPoolSettings connectionPoolSettings,
56-
final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory,
57-
final MongoCredential credential, final CommandListener commandListener,
58-
final String applicationName, final MongoDriverInformation mongoDriverInformation,
59-
final List<MongoCompressor> compressorList, final @Nullable ServerApi serverApi) {
56+
final ServerSettings serverSettings, final ConnectionPoolSettings connectionPoolSettings,
57+
final InternalConnectionPoolSettings internalConnectionPoolSettings,
58+
final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory,
59+
final MongoCredential credential, final CommandListener commandListener,
60+
final String applicationName, final MongoDriverInformation mongoDriverInformation,
61+
final List<MongoCompressor> compressorList, final @Nullable ServerApi serverApi) {
6062
this.clusterId = clusterId;
6163
this.clusterSettings = clusterSettings;
6264
this.serverSettings = serverSettings;
6365
this.connectionPoolSettings = connectionPoolSettings;
66+
this.internalConnectionPoolSettings = internalConnectionPoolSettings;
6467
this.streamFactory = streamFactory;
6568
this.credential = credential == null ? null : new MongoCredentialWithCache(credential);
6669
this.heartbeatStreamFactory = heartbeatStreamFactory;
@@ -86,7 +89,7 @@ mongoDriverInformation, emptyList(), null, serverApi),
8689
ConnectionPool connectionPool = new DefaultConnectionPool(serverId,
8790
new InternalStreamConnectionFactory(clusterSettings.getMode(), streamFactory, credential, applicationName,
8891
mongoDriverInformation, compressorList, commandListener, serverApi),
89-
connectionPoolSettings, sdamProvider);
92+
connectionPoolSettings, internalConnectionPoolSettings, sdamProvider);
9093
SdamServerDescriptionManager sdam = new DefaultSdamServerDescriptionManager(serverId, serverDescriptionChangedListener,
9194
serverListener, serverMonitor, connectionPool, clusterSettings.getMode());
9295
sdamProvider.initialize(sdam);

driver-core/src/main/com/mongodb/internal/connection/DefaultConnectionPool.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ class DefaultConnectionPool implements ConnectionPool {
118118
private final StateAndGeneration stateAndGeneration;
119119
private final OptionalProvider<SdamServerDescriptionManager> sdamProvider;
120120

121+
DefaultConnectionPool(final ServerId serverId, final InternalConnectionFactory internalConnectionFactory,
122+
final ConnectionPoolSettings settings, final OptionalProvider<SdamServerDescriptionManager> sdamProvider) {
123+
this(serverId, internalConnectionFactory, settings, InternalConnectionPoolSettings.builder().build(), sdamProvider);
124+
}
125+
121126
/**
122127
* @param sdamProvider For handling exceptions via the
123128
* <a href="https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst">
@@ -128,7 +133,8 @@ class DefaultConnectionPool implements ConnectionPool {
128133
* otherwise must provide a non-empty {@link Optional}.
129134
*/
130135
DefaultConnectionPool(final ServerId serverId, final InternalConnectionFactory internalConnectionFactory,
131-
final ConnectionPoolSettings settings, final OptionalProvider<SdamServerDescriptionManager> sdamProvider) {
136+
final ConnectionPoolSettings settings, final InternalConnectionPoolSettings internalSettings,
137+
final OptionalProvider<SdamServerDescriptionManager> sdamProvider) {
132138
this.serverId = notNull("serverId", serverId);
133139
this.settings = notNull("settings", settings);
134140
UsageTrackingInternalConnectionItemFactory connectionItemFactory =
@@ -140,7 +146,7 @@ class DefaultConnectionPool implements ConnectionPool {
140146
backgroundMaintenance = new BackgroundMaintenanceManager();
141147
connectionPoolCreated(connectionPoolListener, serverId, settings);
142148
openConcurrencyLimiter = new OpenConcurrencyLimiter(MAX_CONNECTING);
143-
asyncWorkManager = new AsyncWorkManager();
149+
asyncWorkManager = new AsyncWorkManager(internalSettings.isPrestartAsyncWorkManager());
144150
stateAndGeneration = new StateAndGeneration();
145151
connectionGenerationSupplier = new ConnectionGenerationSupplier() {
146152
@Override
@@ -1252,10 +1258,13 @@ private static class AsyncWorkManager implements AutoCloseable {
12521258
@Nullable
12531259
private ExecutorService worker;
12541260

1255-
AsyncWorkManager() {
1261+
AsyncWorkManager(final boolean prestart) {
12561262
state = State.NEW;
12571263
tasks = new LinkedBlockingQueue<>();
12581264
lock = new StampedLock().asWriteLock();
1265+
if (prestart) {
1266+
assertTrue(initUnlessClosed());
1267+
}
12591268
}
12601269

12611270
void enqueue(final Task task) {
@@ -1272,7 +1281,7 @@ void enqueue(final Task task) {
12721281
}
12731282

12741283
/**
1275-
* Invocations of this method must be guarded by {@link #lock}.
1284+
* Invocations of this method must be guarded by {@link #lock}, unless done from the constructor.
12761285
*
12771286
* @return {@code false} iff the {@link #state} is {@link State#CLOSED}.
12781287
*/
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.mongodb.internal.connection;
17+
18+
import com.mongodb.annotations.Immutable;
19+
import com.mongodb.annotations.NotThreadSafe;
20+
import java.util.Objects;
21+
22+
@Immutable
23+
public final class InternalConnectionPoolSettings {
24+
private final boolean prestartAsyncWorkManager;
25+
26+
private InternalConnectionPoolSettings(final Builder builder) {
27+
prestartAsyncWorkManager = builder.prestartAsyncWorkManager;
28+
}
29+
30+
public static Builder builder() {
31+
return new Builder();
32+
}
33+
34+
/**
35+
* Specifies whether to pre-start the asynchronous work manager of the pool.
36+
* <p>
37+
* Default is {@code false}.
38+
*
39+
* @return {@code true} iff pool's asynchronous work manager must be pre-started.
40+
* @see Builder#prestartAsyncWorkManager(boolean)
41+
*/
42+
public boolean isPrestartAsyncWorkManager() {
43+
return prestartAsyncWorkManager;
44+
}
45+
46+
@Override
47+
public boolean equals(final Object o) {
48+
if (this == o) {
49+
return true;
50+
}
51+
if (o == null || getClass() != o.getClass()) {
52+
return false;
53+
}
54+
final InternalConnectionPoolSettings that = (InternalConnectionPoolSettings) o;
55+
return prestartAsyncWorkManager == that.prestartAsyncWorkManager;
56+
}
57+
58+
@Override
59+
public int hashCode() {
60+
return Objects.hash(prestartAsyncWorkManager);
61+
}
62+
63+
@Override
64+
public String toString() {
65+
return "InternalConnectionPoolSettings{"
66+
+ "prestartAsyncWorkManager=" + prestartAsyncWorkManager
67+
+ '}';
68+
}
69+
70+
@NotThreadSafe
71+
public static final class Builder {
72+
private boolean prestartAsyncWorkManager = false;
73+
74+
private Builder() {
75+
}
76+
77+
/**
78+
* Allows to pre-start the asynchronous work manager of the pool.
79+
*
80+
* @param prestart {@code true} iff pool's asynchronous work manager must be pre-started.
81+
* @return {@code this}.
82+
* @see InternalConnectionPoolSettings#isPrestartAsyncWorkManager()
83+
*/
84+
public Builder prestartAsyncWorkManager(final boolean prestart) {
85+
prestartAsyncWorkManager = prestart;
86+
return this;
87+
}
88+
89+
public InternalConnectionPoolSettings build() {
90+
return new InternalConnectionPoolSettings(this);
91+
}
92+
}
93+
}

driver-core/src/main/com/mongodb/internal/connection/LoadBalancedClusterableServerFactory.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class LoadBalancedClusterableServerFactory implements ClusterableServerFa
3939
private final ClusterId clusterId;
4040
private final ServerSettings serverSettings;
4141
private final ConnectionPoolSettings connectionPoolSettings;
42+
private final InternalConnectionPoolSettings internalConnectionPoolSettings;
4243
private final StreamFactory streamFactory;
4344
private final MongoCredentialWithCache credential;
4445
private final CommandListener commandListener;
@@ -48,13 +49,16 @@ public class LoadBalancedClusterableServerFactory implements ClusterableServerFa
4849
private final ServerApi serverApi;
4950

5051
public LoadBalancedClusterableServerFactory(final ClusterId clusterId, final ServerSettings serverSettings,
51-
final ConnectionPoolSettings connectionPoolSettings, final StreamFactory streamFactory,
52-
final MongoCredential credential, final CommandListener commandListener,
52+
final ConnectionPoolSettings connectionPoolSettings,
53+
final InternalConnectionPoolSettings internalConnectionPoolSettings,
54+
final StreamFactory streamFactory, final MongoCredential credential,
55+
final CommandListener commandListener,
5356
final String applicationName, final MongoDriverInformation mongoDriverInformation,
5457
final List<MongoCompressor> compressorList, final ServerApi serverApi) {
5558
this.clusterId = clusterId;
5659
this.serverSettings = serverSettings;
5760
this.connectionPoolSettings = connectionPoolSettings;
61+
this.internalConnectionPoolSettings = internalConnectionPoolSettings;
5862
this.streamFactory = streamFactory;
5963
this.credential = credential == null ? null : new MongoCredentialWithCache(credential);
6064
this.commandListener = commandListener;
@@ -70,8 +74,8 @@ public ClusterableServer create(final ServerAddress serverAddress,
7074
final ServerListener serverListener, final ClusterClock clusterClock) {
7175
ConnectionPool connectionPool = new DefaultConnectionPool(new ServerId(clusterId, serverAddress),
7276
new InternalStreamConnectionFactory(ClusterConnectionMode.LOAD_BALANCED, streamFactory, credential, applicationName,
73-
mongoDriverInformation, compressorList, commandListener, serverApi), connectionPoolSettings,
74-
EmptyProvider.instance());
77+
mongoDriverInformation, compressorList, commandListener, serverApi),
78+
connectionPoolSettings, internalConnectionPoolSettings, EmptyProvider.instance());
7579
connectionPool.ready();
7680

7781
return new LoadBalancedServer(new ServerId(clusterId, serverAddress), connectionPool, new DefaultConnectionFactory(),

driver-core/src/test/functional/com/mongodb/ClusterFixture.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import com.mongodb.internal.connection.AsyncConnection;
5151
import com.mongodb.internal.connection.Cluster;
5252
import com.mongodb.internal.connection.DefaultClusterFactory;
53+
import com.mongodb.internal.connection.InternalConnectionPoolSettings;
5354
import com.mongodb.internal.connection.MongoCredentialWithCache;
5455
import com.mongodb.internal.operation.AsyncReadOperation;
5556
import com.mongodb.internal.operation.AsyncWriteOperation;
@@ -380,7 +381,7 @@ public static Cluster createAsyncCluster(final MongoCredential credential) {
380381
private static Cluster createCluster(final MongoCredential credential, final StreamFactory streamFactory) {
381382
return new DefaultClusterFactory().createCluster(ClusterSettings.builder().hosts(asList(getPrimary())).build(),
382383
ServerSettings.builder().build(),
383-
ConnectionPoolSettings.builder().maxSize(1).build(),
384+
ConnectionPoolSettings.builder().maxSize(1).build(), InternalConnectionPoolSettings.builder().build(),
384385
streamFactory, streamFactory, credential, null, null, null,
385386
Collections.<MongoCompressor>emptyList(), getServerApi());
386387
}
@@ -389,6 +390,7 @@ private static Cluster createCluster(final ConnectionString connectionString, fi
389390
return new DefaultClusterFactory().createCluster(ClusterSettings.builder().applyConnectionString(connectionString).build(),
390391
ServerSettings.builder().build(),
391392
ConnectionPoolSettings.builder().applyConnectionString(connectionString).build(),
393+
InternalConnectionPoolSettings.builder().build(),
392394
streamFactory,
393395
new SocketStreamFactory(SocketSettings.builder().readTimeout(5, SECONDS).build(), getSslSettings(connectionString)),
394396
connectionString.getCredential(),

driver-core/src/test/functional/com/mongodb/internal/connection/SingleServerClusterTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ private void setUpCluster(final ServerAddress serverAddress) {
6969
cluster = new SingleServerCluster(clusterId,
7070
clusterSettings,
7171
new DefaultClusterableServerFactory(clusterId, clusterSettings, ServerSettings.builder().build(),
72-
ConnectionPoolSettings.builder().maxSize(1).build(),
72+
ConnectionPoolSettings.builder().maxSize(1).build(), InternalConnectionPoolSettings.builder().build(),
7373
streamFactory, streamFactory, getCredential(),
7474

7575
null, null, null,

0 commit comments

Comments
 (0)