use of com.mongodb.event.ConnectionCheckedOutEvent in project mongo-java-driver by mongodb.
the class DefaultConnectionPool method getAsync.
@Override
public void getAsync(final SingleResultCallback<InternalConnection> callback) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(format("Asynchronously getting a connection from the pool for server %s", serverId));
}
connectionPoolListener.connectionCheckOutStarted(new ConnectionCheckOutStartedEvent(serverId));
Timeout timeout = Timeout.startNow(settings.getMaxWaitTime(NANOSECONDS));
SingleResultCallback<InternalConnection> eventSendingCallback = (result, failure) -> {
SingleResultCallback<InternalConnection> errHandlingCallback = errorHandlingCallback(callback, LOGGER);
if (failure == null) {
connectionPoolListener.connectionCheckedOut(new ConnectionCheckedOutEvent(getId(result)));
errHandlingCallback.onResult(result, null);
} else {
errHandlingCallback.onResult(null, checkOutFailed(failure));
}
};
try {
stateAndGeneration.throwIfClosedOrPaused();
} catch (RuntimeException e) {
eventSendingCallback.onResult(null, e);
return;
}
asyncWorkManager.enqueue(new Task(timeout, t -> {
if (t != null) {
eventSendingCallback.onResult(null, t);
} else {
PooledConnection connection;
try {
connection = getPooledConnection(timeout);
} catch (RuntimeException e) {
eventSendingCallback.onResult(null, e);
return;
}
if (connection.opened()) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(format("Pooled connection %s to server %s is already open", getId(connection), serverId));
}
eventSendingCallback.onResult(connection, null);
} else {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(format("Pooled connection %s to server %s is not yet open", getId(connection), serverId));
}
openConcurrencyLimiter.openAsyncWithConcurrencyLimit(connection, timeout, eventSendingCallback);
}
}
}));
}
use of com.mongodb.event.ConnectionCheckedOutEvent in project mongo-java-driver by mongodb.
the class DefaultConnectionPool method getPooledConnection.
private PooledConnection getPooledConnection(final long timeout, final TimeUnit timeUnit) {
UsageTrackingInternalConnection internalConnection = pool.get(timeout, timeUnit);
while (shouldPrune(internalConnection)) {
pool.release(internalConnection, true);
internalConnection = pool.get(timeout, timeUnit);
}
connectionPoolListener.connectionCheckedOut(new ConnectionCheckedOutEvent(internalConnection.getDescription().getConnectionId()));
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(format("Checked out connection [%s] to server %s", getId(internalConnection), serverId.getAddress()));
}
return new PooledConnection(internalConnection);
}
use of com.mongodb.event.ConnectionCheckedOutEvent in project mongo-java-driver by mongodb.
the class AbstractConnectionPoolTest method shouldPassAllOutcomes.
@Test
public void shouldPassAllOutcomes() throws Exception {
try {
for (BsonValue cur : definition.getArray("operations")) {
final BsonDocument operation = cur.asDocument();
String name = operation.getString("name").getValue();
if (name.equals("start")) {
String target = operation.getString("target", new BsonString("")).getValue();
executorServiceMap.put(target, Executors.newSingleThreadExecutor(r -> {
Thread result = Executors.defaultThreadFactory().newThread(r);
result.setName(target);
return result;
}));
} else if (name.equals("wait")) {
Thread.sleep(operation.getNumber("ms").intValue());
} else if (name.equals("waitForThread")) {
String target = operation.getString("target", new BsonString("")).getValue();
Exception exceptionFromFuture = futureMap.remove(target).get(5, TimeUnit.SECONDS);
if (exceptionFromFuture != null) {
throw exceptionFromFuture;
}
} else if (name.equals("waitForEvent")) {
Class<?> eventClass = getEventClass(operation.getString("event").getValue());
assumeNotNull(eventClass);
long timeoutMillis = operation.getNumber("timeout", new BsonInt64(TimeUnit.SECONDS.toMillis(5))).longValue();
listener.waitForEvent(eventClass, operation.getNumber("count").intValue(), timeoutMillis, TimeUnit.MILLISECONDS);
} else if (name.equals("clear")) {
pool.invalidate(null);
} else if (name.equals("ready")) {
pool.ready();
} else if (name.equals("close")) {
pool.close();
} else if (name.equals("checkOut") || name.equals("checkIn")) {
Callable<Exception> callable = createCallable(operation);
if (operation.containsKey("thread")) {
String threadTarget = operation.getString("thread").getValue();
ExecutorService executorService = executorServiceMap.get(threadTarget);
futureMap.put(threadTarget, executorService.submit(callable));
} else {
callable.call();
}
} else {
throw new UnsupportedOperationException("No support for " + name);
}
}
} catch (Exception e) {
if (!definition.containsKey("error")) {
throw e;
}
BsonDocument errorDocument = definition.getDocument("error");
String exceptionType = errorDocument.getString("type").getValue();
if (exceptionType.equals("PoolClosedError")) {
assertEquals(IllegalStateException.class, e.getClass());
} else if (exceptionType.equals("WaitQueueTimeoutError")) {
if (e.getClass() != MongoTimeoutException.class) {
throw e;
}
} else {
throw e;
}
}
if (definition.containsKey("events")) {
Iterator<Object> actualEventsIterator = getNonIgnoredActualEvents().iterator();
BsonArray expectedEvents = definition.getArray("events");
for (BsonValue cur : expectedEvents) {
BsonDocument expectedEvent = cur.asDocument();
String type = expectedEvent.getString("type").getValue();
if (type.equals("ConnectionPoolCreated")) {
ConnectionPoolCreatedEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionPoolCreatedEvent.class);
assertAddressMatch(expectedEvent, actualEvent.getServerId().getAddress());
assertEquals(settings, actualEvent.getSettings());
} else if (type.equals("ConnectionPoolCleared")) {
ConnectionPoolClearedEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionPoolClearedEvent.class);
assertAddressMatch(expectedEvent, actualEvent.getServerId().getAddress());
} else if (type.equals("ConnectionPoolReady")) {
ConnectionPoolReadyEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionPoolReadyEvent.class);
assertAddressMatch(expectedEvent, actualEvent.getServerId().getAddress());
} else if (type.equals("ConnectionPoolClosed")) {
ConnectionPoolClosedEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionPoolClosedEvent.class);
assertAddressMatch(expectedEvent, actualEvent.getServerId().getAddress());
} else if (type.equals("ConnectionCreated")) {
ConnectionCreatedEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionCreatedEvent.class);
assertConnectionIdMatch(expectedEvent, actualEvent.getConnectionId());
} else if (type.equals("ConnectionReady")) {
ConnectionReadyEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionReadyEvent.class);
assertAddressMatch(expectedEvent, actualEvent.getConnectionId().getServerId().getAddress());
} else if (type.equals("ConnectionClosed")) {
ConnectionClosedEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionClosedEvent.class);
assertConnectionIdMatch(expectedEvent, actualEvent.getConnectionId());
assertReasonMatch(expectedEvent, actualEvent);
} else if (type.equals("ConnectionCheckOutStarted")) {
ConnectionCheckOutStartedEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionCheckOutStartedEvent.class);
assertAddressMatch(expectedEvent, actualEvent.getServerId().getAddress());
} else if (type.equals("ConnectionCheckOutFailed")) {
ConnectionCheckOutFailedEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionCheckOutFailedEvent.class);
assertAddressMatch(expectedEvent, actualEvent.getServerId().getAddress());
assertReasonMatch(expectedEvent, actualEvent);
} else if (type.equals("ConnectionCheckedOut")) {
ConnectionCheckedOutEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionCheckedOutEvent.class);
assertConnectionIdMatch(expectedEvent, actualEvent.getConnectionId());
} else if (type.equals("ConnectionCheckedIn")) {
ConnectionCheckedInEvent actualEvent = getNextEvent(actualEventsIterator, ConnectionCheckedInEvent.class);
assertConnectionIdMatch(expectedEvent, actualEvent.getConnectionId());
} else {
throw new UnsupportedOperationException("Unsupported event type " + type);
}
}
}
}
use of com.mongodb.event.ConnectionCheckedOutEvent in project mongo-java-driver by mongodb.
the class RetryableWritesProseTest method poolClearedExceptionMustBeRetryable.
@SuppressWarnings("try")
public static <R> void poolClearedExceptionMustBeRetryable(final Function<MongoClientSettings, MongoClient> clientCreator, final Function<MongoCollection<Document>, R> operation, final String operationName, final boolean write) throws InterruptedException, ExecutionException, TimeoutException {
assumeTrue(serverVersionAtLeast(4, 3) && !(write && isStandalone()));
assumeFalse(isServerlessTest());
TestConnectionPoolListener connectionPoolListener = new TestConnectionPoolListener(asList("connectionCheckedOutEvent", "poolClearedEvent", "connectionCheckOutFailedEvent"));
TestCommandListener commandListener = new TestCommandListener(singletonList("commandStartedEvent"), asList("configureFailPoint", "drop"));
MongoClientSettings clientSettings = getMongoClientSettingsBuilder().applyToConnectionPoolSettings(builder -> builder.maxSize(1).addConnectionPoolListener(connectionPoolListener)).applyToServerSettings(builder -> builder.minHeartbeatFrequency(50, TimeUnit.MILLISECONDS).heartbeatFrequency(50, TimeUnit.MILLISECONDS)).retryReads(true).retryWrites(true).addCommandListener(commandListener).build();
BsonDocument configureFailPoint = new BsonDocument().append("configureFailPoint", new BsonString("failCommand")).append("mode", new BsonDocument().append("times", new BsonInt32(1))).append("data", new BsonDocument().append("failCommands", new BsonArray(singletonList(new BsonString(operationName)))).append("errorCode", new BsonInt32(91)).append("errorLabels", write ? new BsonArray(singletonList(new BsonString("RetryableWriteError"))) : new BsonArray()).append("blockConnection", BsonBoolean.valueOf(true)).append("blockTimeMS", new BsonInt32(1000)));
int timeoutSeconds = 5;
try (MongoClient client = clientCreator.apply(clientSettings);
FailPoint ignored = FailPoint.enable(configureFailPoint, client)) {
MongoCollection<Document> collection = client.getDatabase(getDefaultDatabaseName()).getCollection("poolClearedExceptionMustBeRetryable");
collection.drop();
ExecutorService ex = Executors.newFixedThreadPool(2);
try {
Future<R> result1 = ex.submit(() -> operation.apply(collection));
Future<R> result2 = ex.submit(() -> operation.apply(collection));
connectionPoolListener.waitForEvent(ConnectionCheckedOutEvent.class, 1, timeoutSeconds, SECONDS);
connectionPoolListener.waitForEvent(ConnectionPoolClearedEvent.class, 1, timeoutSeconds, SECONDS);
connectionPoolListener.waitForEvent(ConnectionCheckOutFailedEvent.class, 1, timeoutSeconds, SECONDS);
result1.get(timeoutSeconds, SECONDS);
result2.get(timeoutSeconds, SECONDS);
} finally {
ex.shutdownNow();
}
assertEquals(3, commandListener.getCommandStartedEvents().size());
commandListener.getCommandStartedEvents().forEach(event -> assertEquals(operationName, event.getCommandName()));
}
}
use of com.mongodb.event.ConnectionCheckedOutEvent in project mongo-java-driver by mongodb.
the class DefaultConnectionPool method get.
@Override
public InternalConnection get(final long timeoutValue, final TimeUnit timeUnit) {
connectionPoolListener.connectionCheckOutStarted(new ConnectionCheckOutStartedEvent(serverId));
Timeout timeout = Timeout.startNow(timeoutValue, timeUnit);
try {
stateAndGeneration.throwIfClosedOrPaused();
PooledConnection connection = getPooledConnection(timeout);
if (!connection.opened()) {
connection = openConcurrencyLimiter.openOrGetAvailable(connection, timeout);
}
connectionPoolListener.connectionCheckedOut(new ConnectionCheckedOutEvent(getId(connection)));
return connection;
} catch (RuntimeException e) {
throw (RuntimeException) checkOutFailed(e);
}
}
Aggregations