Skip to content

Commit b45d57d

Browse files
authored
Add operation identifier to connection check out/in events (#1105)
JAVA-4907
1 parent 8f6ace4 commit b45d57d

File tree

5 files changed

+140
-21
lines changed

5 files changed

+140
-21
lines changed

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

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,36 @@ public enum Reason {
5353
}
5454

5555
private final ServerId serverId;
56+
private final long operationId;
57+
5658
private final Reason reason;
5759

5860
/**
5961
* Construct an instance
6062
*
6163
* @param serverId the server id
64+
* @param operationId the operation id
6265
* @param reason the reason the connection check out failed
66+
* @since 4.10
6367
*/
64-
public ConnectionCheckOutFailedEvent(final ServerId serverId, final Reason reason) {
68+
public ConnectionCheckOutFailedEvent(final ServerId serverId, final long operationId, final Reason reason) {
6569
this.serverId = notNull("serverId", serverId);
70+
this.operationId = operationId;
6671
this.reason = notNull("reason", reason);
6772
}
6873

74+
/**
75+
* Construct an instance
76+
*
77+
* @param serverId the server id
78+
* @param reason the reason the connection check out failed
79+
* @deprecated Prefer {@link #ConnectionCheckOutFailedEvent(ServerId, long, Reason)}
80+
*/
81+
@Deprecated
82+
public ConnectionCheckOutFailedEvent(final ServerId serverId, final Reason reason) {
83+
this(serverId, -1, reason);
84+
}
85+
6986
/**
7087
* Gets the server id
7188
*
@@ -75,6 +92,16 @@ public ServerId getServerId() {
7592
return serverId;
7693
}
7794

95+
/**
96+
* Gets the operation identifier
97+
*
98+
* @return the operation identifier
99+
* @since 4.10
100+
*/
101+
public long getOperationId() {
102+
return operationId;
103+
}
104+
78105
/**
79106
* Gets the reason for the check out failure.
80107
*
@@ -90,6 +117,7 @@ public String toString() {
90117
return "ConnectionCheckOutFailedEvent{"
91118
+ "server=" + serverId.getAddress()
92119
+ ", clusterId=" + serverId.getClusterId()
120+
+ ", operationId=" + operationId
93121
+ ", reason=" + reason
94122
+ '}';
95123
}

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,29 @@
2727
*/
2828
public final class ConnectionCheckOutStartedEvent {
2929
private final ServerId serverId;
30+
private final long operationId;
3031

3132
/**
3233
* Construct an instance
3334
*
3435
* @param serverId the server id
36+
* @param operationId the operation id
37+
* @since 4.10
3538
*/
36-
public ConnectionCheckOutStartedEvent(final ServerId serverId) {
39+
public ConnectionCheckOutStartedEvent(final ServerId serverId, final long operationId) {
3740
this.serverId = notNull("serverId", serverId);
41+
this.operationId = operationId;
42+
}
43+
44+
/**
45+
* Construct an instance
46+
*
47+
* @param serverId the server id
48+
* @deprecated Prefer {@link ConnectionCheckOutStartedEvent#ConnectionCheckOutStartedEvent(ServerId, long)}
49+
*/
50+
@Deprecated
51+
public ConnectionCheckOutStartedEvent(final ServerId serverId) {
52+
this(serverId, -1);
3853
}
3954

4055
/**
@@ -46,11 +61,22 @@ public ServerId getServerId() {
4661
return serverId;
4762
}
4863

64+
/**
65+
* Gets the operation identifier
66+
*
67+
* @return the operation identifier
68+
* @since 4.10
69+
*/
70+
public long getOperationId() {
71+
return operationId;
72+
}
73+
4974
@Override
5075
public String toString() {
5176
return "ConnectionCheckOutStartedEvent{"
5277
+ "server=" + serverId.getAddress()
5378
+ ", clusterId=" + serverId.getClusterId()
79+
+ ", operationId=" + operationId
5480
+ '}';
5581
}
5682
}

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,30 @@
2727
*/
2828
public final class ConnectionCheckedInEvent {
2929
private final ConnectionId connectionId;
30+
private final long operationId;
31+
3032

3133
/**
3234
* Construct an instance
3335
*
3436
* @param connectionId the connectionId
37+
* @param operationId the operation id
38+
* @since 4.10
3539
*/
36-
public ConnectionCheckedInEvent(final ConnectionId connectionId) {
40+
public ConnectionCheckedInEvent(final ConnectionId connectionId, final long operationId) {
3741
this.connectionId = notNull("connectionId", connectionId);
42+
this.operationId = operationId;
43+
}
44+
45+
/**
46+
* Construct an instance
47+
*
48+
* @param connectionId the connectionId
49+
* @deprecated Prefer {@link #ConnectionCheckedInEvent(ConnectionId, long)}
50+
*/
51+
@Deprecated
52+
public ConnectionCheckedInEvent(final ConnectionId connectionId) {
53+
this(connectionId, -1);
3854
}
3955

4056
/**
@@ -46,12 +62,23 @@ public ConnectionId getConnectionId() {
4662
return connectionId;
4763
}
4864

65+
/**
66+
* Gets the operation identifier
67+
*
68+
* @return the operation identifier
69+
* @since 4.10
70+
*/
71+
public long getOperationId() {
72+
return operationId;
73+
}
74+
4975
@Override
5076
public String toString() {
5177
return "ConnectionCheckedInEvent{"
5278
+ "connectionId=" + connectionId
5379
+ ", server=" + connectionId.getServerId().getAddress()
5480
+ ", clusterId=" + connectionId.getServerId().getClusterId()
81+
+ ", operationId=" + operationId
5582
+ '}';
5683
}
5784
}

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,29 @@
2727
*/
2828
public final class ConnectionCheckedOutEvent {
2929
private final ConnectionId connectionId;
30+
private final long operationId;
3031

3132
/**
3233
* Construct an instance
3334
*
3435
* @param connectionId the connectionId
36+
* @param operationId the operation id
37+
* @since 4.10
3538
*/
36-
public ConnectionCheckedOutEvent(final ConnectionId connectionId) {
39+
public ConnectionCheckedOutEvent(final ConnectionId connectionId, final long operationId) {
3740
this.connectionId = notNull("connectionId", connectionId);
41+
this.operationId = operationId;
42+
}
43+
44+
/**
45+
* Construct an instance
46+
*
47+
* @param connectionId the connectionId
48+
* @deprecated Prefer {@link #ConnectionCheckedOutEvent(ConnectionId, long)}
49+
*/
50+
@Deprecated
51+
public ConnectionCheckedOutEvent(final ConnectionId connectionId) {
52+
this(connectionId, -1);
3853
}
3954

4055
/**
@@ -46,12 +61,23 @@ public ConnectionId getConnectionId() {
4661
return connectionId;
4762
}
4863

64+
/**
65+
* Gets the operation identifier
66+
*
67+
* @return the operation identifier
68+
* @since 4.10
69+
*/
70+
public long getOperationId() {
71+
return operationId;
72+
}
73+
4974
@Override
5075
public String toString() {
5176
return "ConnectionCheckedOutEvent{"
5277
+ "connectionId=" + connectionId
5378
+ ", server=" + connectionId.getServerId().getAddress()
5479
+ ", clusterId=" + connectionId.getServerId().getClusterId()
80+
+ ", operationId=" + operationId
5581
+ '}';
5682
}
5783
}

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

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -168,18 +168,19 @@ public InternalConnection get(final OperationContext operationContext) {
168168

169169
@Override
170170
public InternalConnection get(final OperationContext operationContext, final long timeoutValue, final TimeUnit timeUnit) {
171-
connectionPoolListener.connectionCheckOutStarted(new ConnectionCheckOutStartedEvent(serverId));
171+
connectionPoolListener.connectionCheckOutStarted(new ConnectionCheckOutStartedEvent(serverId, operationContext.getId()));
172172
Timeout timeout = Timeout.startNow(timeoutValue, timeUnit);
173173
try {
174174
stateAndGeneration.throwIfClosedOrPaused();
175175
PooledConnection connection = getPooledConnection(timeout);
176176
if (!connection.opened()) {
177177
connection = openConcurrencyLimiter.openOrGetAvailable(connection, timeout);
178178
}
179-
connectionPoolListener.connectionCheckedOut(new ConnectionCheckedOutEvent(getId(connection)));
179+
connection.checkedOutForOperation(operationContext);
180+
connectionPoolListener.connectionCheckedOut(new ConnectionCheckedOutEvent(getId(connection), operationContext.getId()));
180181
return connection;
181182
} catch (Exception e) {
182-
throw (RuntimeException) checkOutFailed(e);
183+
throw (RuntimeException) checkOutFailed(e, operationContext);
183184
}
184185
}
185186

@@ -188,15 +189,16 @@ public void getAsync(final OperationContext operationContext, final SingleResult
188189
if (LOGGER.isTraceEnabled()) {
189190
LOGGER.trace(format("Asynchronously getting a connection from the pool for server %s", serverId));
190191
}
191-
connectionPoolListener.connectionCheckOutStarted(new ConnectionCheckOutStartedEvent(serverId));
192+
connectionPoolListener.connectionCheckOutStarted(new ConnectionCheckOutStartedEvent(serverId, operationContext.getId()));
192193
Timeout timeout = Timeout.startNow(settings.getMaxWaitTime(NANOSECONDS));
193-
SingleResultCallback<InternalConnection> eventSendingCallback = (result, failure) -> {
194+
SingleResultCallback<PooledConnection> eventSendingCallback = (connection, failure) -> {
194195
SingleResultCallback<InternalConnection> errHandlingCallback = errorHandlingCallback(callback, LOGGER);
195196
if (failure == null) {
196-
connectionPoolListener.connectionCheckedOut(new ConnectionCheckedOutEvent(getId(result)));
197-
errHandlingCallback.onResult(result, null);
197+
connection.checkedOutForOperation(operationContext);
198+
connectionPoolListener.connectionCheckedOut(new ConnectionCheckedOutEvent(getId(connection), operationContext.getId()));
199+
errHandlingCallback.onResult(connection, null);
198200
} else {
199-
errHandlingCallback.onResult(null, checkOutFailed(failure));
201+
errHandlingCallback.onResult(null, checkOutFailed(failure, operationContext));
200202
}
201203
};
202204
try {
@@ -238,20 +240,22 @@ public void getAsync(final OperationContext operationContext, final SingleResult
238240
* and returns {@code t} if it is not {@link MongoOpenConnectionInternalException},
239241
* or returns {@code t.}{@linkplain MongoOpenConnectionInternalException#getCause() getCause()} otherwise.
240242
*/
241-
private Throwable checkOutFailed(final Throwable t) {
243+
private Throwable checkOutFailed(final Throwable t, final OperationContext operationContext) {
242244
Throwable result = t;
245+
Reason reason;
243246
if (t instanceof MongoTimeoutException) {
244-
connectionPoolListener.connectionCheckOutFailed(new ConnectionCheckOutFailedEvent(serverId, Reason.TIMEOUT));
247+
reason = Reason.TIMEOUT;
245248
} else if (t instanceof MongoOpenConnectionInternalException) {
246-
connectionPoolListener.connectionCheckOutFailed(new ConnectionCheckOutFailedEvent(serverId, Reason.CONNECTION_ERROR));
249+
reason = Reason.CONNECTION_ERROR;
247250
result = t.getCause();
248251
} else if (t instanceof MongoConnectionPoolClearedException) {
249-
connectionPoolListener.connectionCheckOutFailed(new ConnectionCheckOutFailedEvent(serverId, Reason.CONNECTION_ERROR));
252+
reason = Reason.CONNECTION_ERROR;
250253
} else if (ConcurrentPool.isPoolClosedException(t)) {
251-
connectionPoolListener.connectionCheckOutFailed(new ConnectionCheckOutFailedEvent(serverId, Reason.POOL_CLOSED));
254+
reason = Reason.POOL_CLOSED;
252255
} else {
253-
connectionPoolListener.connectionCheckOutFailed(new ConnectionCheckOutFailedEvent(serverId, Reason.UNKNOWN));
256+
reason = Reason.UNKNOWN;
254257
}
258+
connectionPoolListener.connectionCheckOutFailed(new ConnectionCheckOutFailedEvent(serverId, operationContext.getId(), reason));
255259
return result;
256260
}
257261

@@ -516,6 +520,7 @@ private class PooledConnection implements InternalConnection {
516520
private final UsageTrackingInternalConnection wrapped;
517521
private final AtomicBoolean isClosed = new AtomicBoolean();
518522
private Connection.PinningMode pinningMode;
523+
private OperationContext operationContext;
519524

520525
PooledConnection(final UsageTrackingInternalConnection wrapped) {
521526
this.wrapped = notNull("wrapped", wrapped);
@@ -526,6 +531,13 @@ public int getGeneration() {
526531
return wrapped.getGeneration();
527532
}
528533

534+
/**
535+
* Associates this with the operation context and establishes the checked out start time
536+
*/
537+
public void checkedOutForOperation(final OperationContext operationContext) {
538+
this.operationContext = operationContext;
539+
}
540+
529541
@Override
530542
public void open() {
531543
assertFalse(isClosed.get());
@@ -559,7 +571,7 @@ public void close() {
559571
// All but the first call is a no-op
560572
if (!isClosed.getAndSet(true)) {
561573
unmarkAsPinned();
562-
connectionPoolListener.connectionCheckedIn(new ConnectionCheckedInEvent(getId(wrapped)));
574+
connectionPoolListener.connectionCheckedIn(new ConnectionCheckedInEvent(getId(wrapped), operationContext.getId()));
563575
if (LOGGER.isTraceEnabled()) {
564576
LOGGER.trace(format("Checked in connection [%s] to server %s", getId(wrapped), serverId.getAddress()));
565577
}
@@ -731,7 +743,7 @@ public ServerDescription getInitialServerDescription() {
731743
/**
732744
* This internal exception is used to express an exceptional situation encountered when opening a connection.
733745
* It exists because it allows consolidating the code that sends events for exceptional situations in a
734-
* {@linkplain #checkOutFailed(Throwable) single place}, it must not be observable by an external code.
746+
* {@linkplain #checkOutFailed(Throwable, OperationContext) single place}, it must not be observable by an external code.
735747
*/
736748
private static final class MongoOpenConnectionInternalException extends RuntimeException {
737749
private static final long serialVersionUID = 1;
@@ -919,7 +931,7 @@ private PooledConnection openWithConcurrencyLimit(final PooledConnection connect
919931
* </ul>
920932
*/
921933
void openAsyncWithConcurrencyLimit(
922-
final PooledConnection connection, final Timeout timeout, final SingleResultCallback<InternalConnection> callback) {
934+
final PooledConnection connection, final Timeout timeout, final SingleResultCallback<PooledConnection> callback) {
923935
PooledConnection availableConnection;
924936
try {//phase one
925937
availableConnection = acquirePermitOrGetAvailableOpenedConnection(true, timeout);

0 commit comments

Comments
 (0)