Skip to content

Commit bbee638

Browse files
committed
Add durations to connection pool events
JAVA-5076
1 parent c4662b1 commit bbee638

File tree

10 files changed

+291
-53
lines changed

10 files changed

+291
-53
lines changed

driver-core/src/main/com/mongodb/ConnectionString.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.mongodb.connection.ClusterSettings;
2020
import com.mongodb.connection.ConnectionPoolSettings;
2121
import com.mongodb.connection.SocketSettings;
22+
import com.mongodb.event.ConnectionCreatedEvent;
2223
import com.mongodb.internal.diagnostics.logging.Logger;
2324
import com.mongodb.internal.diagnostics.logging.Loggers;
2425
import com.mongodb.internal.dns.DefaultDnsResolver;
@@ -132,8 +133,9 @@
132133
* <ul>
133134
* <li>{@code maxPoolSize=n}: The maximum number of connections in the connection pool.</li>
134135
* <li>{@code minPoolSize=n}: The minimum number of connections in the connection pool.</li>
135-
* <li>{@code waitQueueTimeoutMS=ms}: The maximum wait time in milliseconds that a thread may wait for a connection to
136-
* become available.</li>
136+
* <li>{@code waitQueueTimeoutMS=ms}: The maximum duration to wait for either an available connection
137+
* (limited by {@link #getMaxConnectionPoolSize()}),
138+
* or a {@linkplain ConnectionCreatedEvent newly created connection} (limited by {@link #getMaxConnecting()}).</li>
137139
* <li>{@code maxConnecting=n}: The maximum number of connections a pool may be establishing concurrently.</li>
138140
* </ul>
139141
* <p>Write concern configuration:</p>
@@ -1366,15 +1368,18 @@ public Integer getMinConnectionPoolSize() {
13661368
/**
13671369
* Gets the maximum connection pool size specified in the connection string.
13681370
* @return the maximum connection pool size
1371+
* @see ConnectionPoolSettings#getMaxSize()
13691372
*/
13701373
@Nullable
13711374
public Integer getMaxConnectionPoolSize() {
13721375
return maxConnectionPoolSize;
13731376
}
13741377

13751378
/**
1376-
* Gets the maximum wait time of a thread waiting for a connection specified in the connection string.
1377-
* @return the maximum wait time of a thread waiting for a connection
1379+
* The maximum duration to wait for either an available connection (limited by {@link #getMaxConnectionPoolSize()}),
1380+
* or a {@linkplain ConnectionCreatedEvent newly created connection} (limited by {@link #getMaxConnecting()}).
1381+
* @return the maximum wait time when waiting for a connection
1382+
* @see ConnectionPoolSettings#getMaxWaitTime(TimeUnit)
13781383
*/
13791384
@Nullable
13801385
public Integer getMaxWaitTime() {

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

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.mongodb.ConnectionString;
2020
import com.mongodb.annotations.Immutable;
2121
import com.mongodb.annotations.NotThreadSafe;
22+
import com.mongodb.event.ConnectionCheckedOutEvent;
2223
import com.mongodb.event.ConnectionCreatedEvent;
2324
import com.mongodb.event.ConnectionPoolListener;
2425
import com.mongodb.event.ConnectionReadyEvent;
@@ -112,13 +113,15 @@ public Builder applySettings(final ConnectionPoolSettings connectionPoolSettings
112113
}
113114

114115
/**
115-
* <p>The maximum number of connections allowed. Those connections will be kept in the pool when idle. Once the pool is exhausted,
116-
* any operation requiring a connection will block waiting for an available connection.</p>
116+
* <p>The maximum number of connections allowed. Those connections will be kept in the pool when idle. Once the pool is exhausted, any
117+
* operation requiring a connection will block waiting for an available connection.
118+
* The duration of such waiting is affected by the {@link #getMaxWaitTime(TimeUnit)} setting.</p>
117119
*
118120
* <p>Default is 100.</p>
119121
*
120122
* @param maxSize the maximum number of connections in the pool; if 0, then there is no limit.
121123
* @return this
124+
* @see #getMaxSize()
122125
*/
123126
public Builder maxSize(final int maxSize) {
124127
this.maxSize = maxSize;
@@ -140,13 +143,19 @@ public Builder minSize(final int minSize) {
140143
}
141144

142145
/**
143-
* <p>The maximum time that a thread may wait for a connection to become available.</p>
146+
* <p>
147+
* The maximum duration to wait for either an available connection (limited by {@link #getMaxSize()}),
148+
* or a {@linkplain ConnectionCreatedEvent newly created connection} (limited by {@link #getMaxConnecting()}).
149+
* Note that the latter then has to be {@linkplain ConnectionReadyEvent established}
150+
* before {@link ConnectionCheckedOutEvent checking out is completed}.
151+
* Establishment of a connection is not controlled by this setting.</p>
144152
*
145153
* <p>Default is 2 minutes. A value of 0 means that it will not wait. A negative value means it will wait indefinitely.</p>
146154
*
147155
* @param maxWaitTime the maximum amount of time to wait
148156
* @param timeUnit the TimeUnit for this wait period
149157
* @return this
158+
* @see #getMaxWaitTime(TimeUnit)
150159
*/
151160
public Builder maxWaitTime(final long maxWaitTime, final TimeUnit timeUnit) {
152161
this.maxWaitTimeMS = MILLISECONDS.convert(maxWaitTime, timeUnit);
@@ -293,11 +302,14 @@ public Builder applyConnectionString(final ConnectionString connectionString) {
293302

294303
/**
295304
* <p>The maximum number of connections allowed. Those connections will be kept in the pool when idle. Once the pool is exhausted, any
296-
* operation requiring a connection will block waiting for an available connection.</p>
305+
* operation requiring a connection will block waiting for an available connection.
306+
* The duration of such waiting is affected by the {@link #getMaxWaitTime(TimeUnit)} setting.</p>
297307
*
298308
* <p>Default is 100.</p>
299309
*
300310
* @return the maximum number of connections in the pool; if 0, then there is no limit.
311+
* @see Builder#maxSize(int)
312+
* @see ConnectionString#getMaxConnectionPoolSize()
301313
*/
302314
public int getMaxSize() {
303315
return maxSize;
@@ -316,12 +328,19 @@ public int getMinSize() {
316328
}
317329

318330
/**
319-
* <p>The maximum time that a thread may wait for a connection to become available.</p>
331+
* <p>
332+
* The maximum duration to wait for either an available connection (limited by {@link #getMaxSize()}),
333+
* or a {@linkplain ConnectionCreatedEvent newly created connection} (limited by {@link #getMaxConnecting()}).
334+
* Note that the latter then has to be {@linkplain ConnectionReadyEvent established}
335+
* before {@link ConnectionCheckedOutEvent checking out is completed}.
336+
* Establishment of a connection is not controlled by this setting.</p>
320337
*
321338
* <p>Default is 2 minutes. A value of 0 means that it will not wait. A negative value means it will wait indefinitely.</p>
322339
*
323340
* @param timeUnit the TimeUnit for this wait period
324341
* @return the maximum amount of time to wait in the given TimeUnits
342+
* @see Builder#maxWaitTime(long, TimeUnit)
343+
* @see ConnectionString#getMaxWaitTime()
325344
*/
326345
public long getMaxWaitTime(final TimeUnit timeUnit) {
327346
return timeUnit.convert(maxWaitTimeMS, MILLISECONDS);
@@ -384,10 +403,14 @@ public List<ConnectionPoolListener> getConnectionPoolListeners() {
384403
* Establishment of a connection is a part of its life cycle
385404
* starting after a {@link ConnectionCreatedEvent} and ending before a {@link ConnectionReadyEvent}.
386405
* <p>
406+
* This limit may cause waiting when checking out a connection.
407+
* The duration of such waiting is affected by the {@link #getMaxWaitTime(TimeUnit)} setting.</p>
408+
* <p>
387409
* Default is 2.</p>
388410
*
389411
* @return The maximum number of connections a pool may be establishing concurrently.
390412
* @see Builder#maxConnecting(int)
413+
* @see ConnectionString#getMaxConnecting()
391414
* @since 4.4
392415
*/
393416
public int getMaxConnecting() {

driver-core/src/main/com/mongodb/event/ConnectionCheckOutFailedEvent.java

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616

1717
package com.mongodb.event;
1818

19+
import com.mongodb.connection.ConnectionPoolSettings;
1920
import com.mongodb.connection.ServerId;
2021

22+
import java.util.concurrent.TimeUnit;
23+
24+
import static com.mongodb.assertions.Assertions.isTrueArgument;
2125
import static com.mongodb.assertions.Assertions.notNull;
2226

2327
/**
@@ -54,8 +58,25 @@ public enum Reason {
5458

5559
private final ServerId serverId;
5660
private final long operationId;
57-
5861
private final Reason reason;
62+
private final long elapsedTimeNanos;
63+
64+
/**
65+
* Constructs an instance.
66+
*
67+
* @param serverId The server ID. See {@link #getServerId()}.
68+
* @param operationId The operation ID. See {@link #getOperationId()}.
69+
* @param reason The reason the connection check out failed. See {@link #getReason()}.
70+
* @param elapsedTimeNanos The time it took while trying to check out the connection. See {@link #getElapsedTime(TimeUnit)}.
71+
* @since VAKOTODO
72+
*/
73+
public ConnectionCheckOutFailedEvent(final ServerId serverId, final long operationId, final Reason reason, final long elapsedTimeNanos) {
74+
this.serverId = notNull("serverId", serverId);
75+
this.operationId = operationId;
76+
this.reason = notNull("reason", reason);
77+
isTrueArgument("waited time is not negative", elapsedTimeNanos >= 0);
78+
this.elapsedTimeNanos = elapsedTimeNanos;
79+
}
5980

6081
/**
6182
* Construct an instance
@@ -64,11 +85,12 @@ public enum Reason {
6485
* @param operationId the operation id
6586
* @param reason the reason the connection check out failed
6687
* @since 4.10
88+
* @deprecated Prefer {@link ConnectionCheckOutFailedEvent#ConnectionCheckOutFailedEvent(ServerId, long, Reason, long)}.
89+
* If this constructor is used, then {@link #getElapsedTime(TimeUnit)} is 0.
6790
*/
91+
@Deprecated
6892
public ConnectionCheckOutFailedEvent(final ServerId serverId, final long operationId, final Reason reason) {
69-
this.serverId = notNull("serverId", serverId);
70-
this.operationId = operationId;
71-
this.reason = notNull("reason", reason);
93+
this(serverId, operationId, reason, 0);
7294
}
7395

7496
/**
@@ -77,6 +99,7 @@ public ConnectionCheckOutFailedEvent(final ServerId serverId, final long operati
7799
* @param serverId the server id
78100
* @param reason the reason the connection check out failed
79101
* @deprecated Prefer {@link #ConnectionCheckOutFailedEvent(ServerId, long, Reason)}
102+
* If this constructor is used, then {@link #getOperationId()} is -1.
80103
*/
81104
@Deprecated
82105
public ConnectionCheckOutFailedEvent(final ServerId serverId, final Reason reason) {
@@ -112,13 +135,35 @@ public Reason getReason() {
112135
return reason;
113136
}
114137

138+
/**
139+
* The time it took to check out the connection.
140+
* More specifically, the time elapsed between the {@link ConnectionCheckOutStartedEvent} emitted by the same checking out and this event.
141+
* <p>
142+
* Naturally, if a new connection was not {@linkplain ConnectionCreatedEvent created}
143+
* and {@linkplain ConnectionReadyEvent established} as part of checking out,
144+
`` * this duration is usually not greater than {@link ConnectionPoolSettings#getMaxWaitTime(TimeUnit)},
145+
* but may occasionally be greater than that, because the driver does not provide hard real-time guarantees.</p>
146+
* <p>
147+
* This duration does not include the time to deliver the {@link ConnectionCheckOutStartedEvent}.
148+
* Be warned that this may change.</p>
149+
*
150+
* @param timeUnit The time unit of the result.
151+
* {@link TimeUnit#convert(long, TimeUnit)} specifies how the conversion from nanoseconds to {@code timeUnit} is done.
152+
* @return The time it took to establish the connection.
153+
* @since VAKOTODO
154+
*/
155+
public long getElapsedTime(final TimeUnit timeUnit) {
156+
return timeUnit.convert(elapsedTimeNanos, TimeUnit.NANOSECONDS);
157+
}
158+
115159
@Override
116160
public String toString() {
117161
return "ConnectionCheckOutFailedEvent{"
118162
+ "server=" + serverId.getAddress()
119163
+ ", clusterId=" + serverId.getClusterId()
120164
+ ", operationId=" + operationId
121165
+ ", reason=" + reason
166+
+ ", elapsedTimeNanos=" + elapsedTimeNanos
122167
+ '}';
123168
}
124169
}

driver-core/src/main/com/mongodb/event/ConnectionCheckedOutEvent.java

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
package com.mongodb.event;
1818

1919
import com.mongodb.connection.ConnectionId;
20+
import com.mongodb.connection.ConnectionPoolSettings;
2021

22+
import java.util.concurrent.TimeUnit;
23+
24+
import static com.mongodb.assertions.Assertions.isTrueArgument;
2125
import static com.mongodb.assertions.Assertions.notNull;
2226

2327
/**
@@ -28,24 +32,43 @@
2832
public final class ConnectionCheckedOutEvent {
2933
private final ConnectionId connectionId;
3034
private final long operationId;
35+
private final long elapsedTimeNanos;
36+
37+
/**
38+
* Constructs an instance.
39+
*
40+
* @param connectionId The connection ID. See {@link #getConnectionId()}.
41+
* @param operationId The operation ID. See {@link #getOperationId()}.
42+
* @param elapsedTimeNanos The time it took to check out the connection. See {@link #getElapsedTime(TimeUnit)}.
43+
* @since VAKOTODO
44+
*/
45+
public ConnectionCheckedOutEvent(final ConnectionId connectionId, final long operationId, final long elapsedTimeNanos) {
46+
this.connectionId = notNull("connectionId", connectionId);
47+
this.operationId = operationId;
48+
isTrueArgument("waited time is not negative", elapsedTimeNanos >= 0);
49+
this.elapsedTimeNanos = elapsedTimeNanos;
50+
}
3151

3252
/**
3353
* Construct an instance
3454
*
3555
* @param connectionId the connectionId
3656
* @param operationId the operation id
3757
* @since 4.10
58+
* @deprecated Prefer {@link ConnectionCheckedOutEvent#ConnectionCheckedOutEvent(ConnectionId, long, long)}.
59+
* If this constructor is used, then {@link #getElapsedTime(TimeUnit)} is 0.
3860
*/
61+
@Deprecated
3962
public ConnectionCheckedOutEvent(final ConnectionId connectionId, final long operationId) {
40-
this.connectionId = notNull("connectionId", connectionId);
41-
this.operationId = operationId;
63+
this(connectionId, operationId, 0);
4264
}
4365

4466
/**
4567
* Construct an instance
4668
*
4769
* @param connectionId the connectionId
48-
* @deprecated Prefer {@link #ConnectionCheckedOutEvent(ConnectionId, long)}
70+
* @deprecated Prefer {@link #ConnectionCheckedOutEvent(ConnectionId, long)}.
71+
* If this constructor is used, then {@link #getOperationId()} is -1.
4972
*/
5073
@Deprecated
5174
public ConnectionCheckedOutEvent(final ConnectionId connectionId) {
@@ -71,13 +94,35 @@ public long getOperationId() {
7194
return operationId;
7295
}
7396

97+
/**
98+
* The time it took to check out the connection.
99+
* More specifically, the time elapsed between the {@link ConnectionCheckOutStartedEvent} emitted by the same checking out and this event.
100+
* <p>
101+
* Naturally, if a new connection was not {@linkplain ConnectionCreatedEvent created}
102+
* and {@linkplain ConnectionReadyEvent established} as part of checking out,
103+
* this duration is usually not greater than {@link ConnectionPoolSettings#getMaxWaitTime(TimeUnit)},
104+
* but may occasionally be greater than that, because the driver does not provide hard real-time guarantees.</p>
105+
* <p>
106+
* This duration does not include the time to deliver the {@link ConnectionCheckOutStartedEvent}.
107+
* Be warned that this may change.</p>
108+
*
109+
* @param timeUnit The time unit of the result.
110+
* {@link TimeUnit#convert(long, TimeUnit)} specifies how the conversion from nanoseconds to {@code timeUnit} is done.
111+
* @return The time it took to establish the connection.
112+
* @since VAKOTODO
113+
*/
114+
public long getElapsedTime(final TimeUnit timeUnit) {
115+
return timeUnit.convert(elapsedTimeNanos, TimeUnit.NANOSECONDS);
116+
}
117+
74118
@Override
75119
public String toString() {
76120
return "ConnectionCheckedOutEvent{"
77121
+ "connectionId=" + connectionId
78122
+ ", server=" + connectionId.getServerId().getAddress()
79123
+ ", clusterId=" + connectionId.getServerId().getClusterId()
80124
+ ", operationId=" + operationId
125+
+ ", elapsedTimeNanos=" + elapsedTimeNanos
81126
+ '}';
82127
}
83128
}

0 commit comments

Comments
 (0)