Search in sources :

Example 11 with RetryState

use of com.mongodb.internal.async.function.RetryState in project mongo-java-driver by mongodb.

the class FindOperation method executeAsync.

@Override
public void executeAsync(final AsyncReadBinding binding, final SingleResultCallback<AsyncBatchCursor<T>> callback) {
    RetryState retryState = initialRetryState(retryReads);
    binding.retain();
    AsyncCallbackSupplier<AsyncBatchCursor<T>> asyncRead = CommandOperationHelper.<AsyncBatchCursor<T>>decorateReadWithRetries(retryState, funcCallback -> {
        logRetryExecute(retryState);
        withAsyncSourceAndConnection(binding::getReadConnectionSource, false, funcCallback, (source, connection, releasingCallback) -> {
            if (retryState.breakAndCompleteIfRetryAnd(() -> !canRetryRead(source.getServerDescription(), connection.getDescription(), binding.getSessionContext()), releasingCallback)) {
                return;
            }
            if (serverIsAtLeastVersionThreeDotTwo(connection.getDescription())) {
                final SingleResultCallback<AsyncBatchCursor<T>> wrappedCallback = exceptionTransformingCallback(releasingCallback);
                createReadCommandAndExecuteAsync(retryState, binding, source, namespace.getDatabaseName(), getCommandCreator(binding.getSessionContext()), CommandResultDocumentCodec.create(decoder, FIRST_BATCH), asyncTransformer(), connection, wrappedCallback);
            } else {
                retryState.markAsLastAttempt();
                validateFindOptions(source, connection, binding.getSessionContext().getReadConcern(), collation, allowDiskUse, new AsyncCallableWithConnectionAndSource() {

                    @Override
                    public void call(final AsyncConnectionSource source, final AsyncConnection connection, final Throwable t) {
                        if (t != null) {
                            releasingCallback.onResult(null, t);
                        } else {
                            connection.queryAsync(namespace, asDocument(connection.getDescription(), binding.getReadPreference()), projection, skip, limit, batchSize, isSecondaryOk() || binding.getReadPreference().isSecondaryOk(), isTailableCursor(), isAwaitData(), isNoCursorTimeout(), isPartial(), isOplogReplay(), decoder, binding.getRequestContext(), new SingleResultCallback<QueryResult<T>>() {

                                @Override
                                public void onResult(final QueryResult<T> result, final Throwable t) {
                                    if (t != null) {
                                        releasingCallback.onResult(null, t);
                                    } else {
                                        releasingCallback.onResult(new AsyncQueryBatchCursor<T>(result, limit, batchSize, getMaxTimeForCursor(), decoder, source, connection), null);
                                    }
                                }
                            });
                        }
                    }
                });
            }
        });
    }).whenComplete(binding::release);
    asyncRead.get(errorHandlingCallback(callback, LOGGER));
}
Also used : AsyncReadBinding(com.mongodb.internal.binding.AsyncReadBinding) ServerDescription(com.mongodb.connection.ServerDescription) CommandOperationHelper.initialRetryState(com.mongodb.internal.operation.CommandOperationHelper.initialRetryState) BsonValue(org.bson.BsonValue) DocumentHelper.putIfNotNull(com.mongodb.internal.operation.DocumentHelper.putIfNotNull) ConnectionDescription(com.mongodb.connection.ConnectionDescription) ExplainHelper.asExplainCommand(com.mongodb.internal.operation.ExplainHelper.asExplainCommand) DocumentHelper.putIfNotNullOrEmpty(com.mongodb.internal.operation.DocumentHelper.putIfNotNullOrEmpty) MIN_WIRE_VERSION(com.mongodb.internal.operation.ServerVersionHelper.MIN_WIRE_VERSION) CursorType(com.mongodb.CursorType) AsyncCallableWithConnectionAndSource(com.mongodb.internal.operation.OperationHelper.AsyncCallableWithConnectionAndSource) OperationHelper.validateFindOptions(com.mongodb.internal.operation.OperationHelper.validateFindOptions) OperationHelper.canRetryRead(com.mongodb.internal.operation.OperationHelper.canRetryRead) QueryResult(com.mongodb.internal.connection.QueryResult) OperationHelper.withSourceAndConnection(com.mongodb.internal.operation.OperationHelper.withSourceAndConnection) ConnectionSource(com.mongodb.internal.binding.ConnectionSource) ReadBinding(com.mongodb.internal.binding.ReadBinding) AsyncCallbackSupplier(com.mongodb.internal.async.function.AsyncCallbackSupplier) OperationReadConcernHelper.appendReadConcernToCommand(com.mongodb.internal.operation.OperationReadConcernHelper.appendReadConcernToCommand) NoOpSessionContext(com.mongodb.internal.connection.NoOpSessionContext) SingleResultCallback(com.mongodb.internal.async.SingleResultCallback) Decoder(org.bson.codecs.Decoder) RetryState(com.mongodb.internal.async.function.RetryState) CommandReadTransformerAsync(com.mongodb.internal.operation.CommandOperationHelper.CommandReadTransformerAsync) Assertions.notNull(com.mongodb.assertions.Assertions.notNull) ReadPreference.primary(com.mongodb.ReadPreference.primary) ExplainVerbosity(com.mongodb.ExplainVerbosity) ReadPreference(com.mongodb.ReadPreference) CommandOperationHelper.logRetryExecute(com.mongodb.internal.operation.CommandOperationHelper.logRetryExecute) OperationHelper.cursorDocumentToQueryResult(com.mongodb.internal.operation.OperationHelper.cursorDocumentToQueryResult) CommandCreator(com.mongodb.internal.operation.CommandOperationHelper.CommandCreator) BsonBoolean(org.bson.BsonBoolean) MongoCommandException(com.mongodb.MongoCommandException) ErrorHandlingResultCallback.errorHandlingCallback(com.mongodb.internal.async.ErrorHandlingResultCallback.errorHandlingCallback) CommandReadTransformer(com.mongodb.internal.operation.CommandOperationHelper.CommandReadTransformer) BsonString(org.bson.BsonString) CommandOperationHelper.createReadCommandAndExecuteAsync(com.mongodb.internal.operation.CommandOperationHelper.createReadCommandAndExecuteAsync) MongoQueryException(com.mongodb.MongoQueryException) Supplier(java.util.function.Supplier) BsonDocument(org.bson.BsonDocument) LOGGER(com.mongodb.internal.operation.OperationHelper.LOGGER) Connection(com.mongodb.internal.connection.Connection) SHARD_ROUTER(com.mongodb.connection.ServerType.SHARD_ROUTER) BsonInt64(org.bson.BsonInt64) ServerVersionHelper.serverIsAtLeastVersionThreeDotTwo(com.mongodb.internal.operation.ServerVersionHelper.serverIsAtLeastVersionThreeDotTwo) AsyncConnectionSource(com.mongodb.internal.binding.AsyncConnectionSource) SessionContext(com.mongodb.internal.session.SessionContext) Collation(com.mongodb.client.model.Collation) MongoNamespace(com.mongodb.MongoNamespace) CommandOperationHelper.createReadCommandAndExecute(com.mongodb.internal.operation.CommandOperationHelper.createReadCommandAndExecute) CommandOperationHelper.decorateReadWithRetries(com.mongodb.internal.operation.CommandOperationHelper.decorateReadWithRetries) TimeUnit(java.util.concurrent.TimeUnit) AsyncBatchCursor(com.mongodb.internal.async.AsyncBatchCursor) Assertions.isTrueArgument(com.mongodb.assertions.Assertions.isTrueArgument) OperationHelper.withAsyncSourceAndConnection(com.mongodb.internal.operation.OperationHelper.withAsyncSourceAndConnection) Nullable(com.mongodb.lang.Nullable) BsonInt32(org.bson.BsonInt32) AsyncConnection(com.mongodb.internal.connection.AsyncConnection) AsyncBatchCursor(com.mongodb.internal.async.AsyncBatchCursor) SingleResultCallback(com.mongodb.internal.async.SingleResultCallback) QueryResult(com.mongodb.internal.connection.QueryResult) OperationHelper.cursorDocumentToQueryResult(com.mongodb.internal.operation.OperationHelper.cursorDocumentToQueryResult) AsyncConnectionSource(com.mongodb.internal.binding.AsyncConnectionSource) AsyncConnection(com.mongodb.internal.connection.AsyncConnection) AsyncCallableWithConnectionAndSource(com.mongodb.internal.operation.OperationHelper.AsyncCallableWithConnectionAndSource) CommandOperationHelper.initialRetryState(com.mongodb.internal.operation.CommandOperationHelper.initialRetryState) RetryState(com.mongodb.internal.async.function.RetryState)

Example 12 with RetryState

use of com.mongodb.internal.async.function.RetryState in project mongo-java-driver by mongodb.

the class MixedBulkWriteOperation method execute.

/**
 * Executes a bulk write operation.
 *
 * @param binding the WriteBinding        for the operation
 * @return the bulk write result.
 * @throws MongoBulkWriteException if a failure to complete the bulk write is detected based on the server response
 */
@Override
public BulkWriteResult execute(final WriteBinding binding) {
    /* We cannot use the tracking of attempts built in the `RetryState` class because conceptually we have to maintain multiple attempt
         * counters while executing a single bulk write operation:
         * - a counter that limits attempts to select server and checkout a connection before we created a batch;
         * - a counter per each batch that limits attempts to execute the specific batch.
         * Fortunately, these counters do not exist concurrently with each other. While maintaining the counters manually,
         * we must adhere to the contract of `RetryingSyncSupplier`. When the retry timeout is implemented, there will be no counters,
         * and the code related to the attempt tracking in `BulkWriteTracker` will be removed. */
    RetryState retryState = new RetryState();
    BulkWriteTracker.attachNew(retryState, retryWrites);
    Supplier<BulkWriteResult> retryingBulkWrite = decorateWriteWithRetries(retryState, () -> {
        logRetryExecute(retryState);
        return withSourceAndConnection(binding::getWriteConnectionSource, true, (source, connection) -> {
            ConnectionDescription connectionDescription = connection.getDescription();
            int maxWireVersion = connectionDescription.getMaxWireVersion();
            // attach `maxWireVersion` ASAP because it is used to check whether we can retry
            retryState.attach(AttachmentKeys.maxWireVersion(), maxWireVersion, true);
            BulkWriteTracker bulkWriteTracker = retryState.attachment(AttachmentKeys.bulkWriteTracker()).orElseThrow(Assertions::fail);
            SessionContext sessionContext = binding.getSessionContext();
            WriteConcern writeConcern = getAppliedWriteConcern(sessionContext);
            if (!retryState.isFirstAttempt() && !isRetryableWrite(retryWrites, writeConcern, source.getServerDescription(), connectionDescription, sessionContext)) {
                RuntimeException prospectiveFailedResult = (RuntimeException) retryState.exception().orElse(null);
                retryState.breakAndThrowIfRetryAnd(() -> !(prospectiveFailedResult instanceof MongoWriteConcernWithResponseException));
                bulkWriteTracker.batch().ifPresent(bulkWriteBatch -> {
                    assertTrue(prospectiveFailedResult instanceof MongoWriteConcernWithResponseException);
                    bulkWriteBatch.addResult((BsonDocument) ((MongoWriteConcernWithResponseException) prospectiveFailedResult).getResponse());
                    BulkWriteTracker.attachNext(retryState, bulkWriteBatch);
                });
            }
            validateWriteRequests(connectionDescription, bypassDocumentValidation, writeRequests, writeConcern);
            if (writeConcern.isAcknowledged() || serverIsAtLeastVersionThreeDotSix(connectionDescription)) {
                if (!bulkWriteTracker.batch().isPresent()) {
                    BulkWriteTracker.attachNew(retryState, BulkWriteBatch.createBulkWriteBatch(namespace, source.getServerDescription(), connectionDescription, ordered, writeConcern, bypassDocumentValidation, retryWrites, writeRequests, sessionContext));
                }
                logRetryExecute(retryState);
                return executeBulkWriteBatch(retryState, binding, connection, maxWireVersion);
            } else {
                retryState.markAsLastAttempt();
                return executeLegacyBatches(binding, connection);
            }
        });
    });
    try {
        return retryingBulkWrite.get();
    } catch (MongoException e) {
        throw transformWriteException(e);
    }
}
Also used : MongoException(com.mongodb.MongoException) Assertions(com.mongodb.assertions.Assertions) BulkWriteResult(com.mongodb.bulk.BulkWriteResult) ConnectionDescription(com.mongodb.connection.ConnectionDescription) MongoWriteConcernWithResponseException(com.mongodb.internal.connection.MongoWriteConcernWithResponseException) WriteConcern(com.mongodb.WriteConcern) SessionContext(com.mongodb.internal.session.SessionContext) RetryState(com.mongodb.internal.async.function.RetryState)

Aggregations

RetryState (com.mongodb.internal.async.function.RetryState)12 MongoCommandException (com.mongodb.MongoCommandException)9 ConnectionDescription (com.mongodb.connection.ConnectionDescription)8 Assertions.notNull (com.mongodb.assertions.Assertions.notNull)7 ErrorHandlingResultCallback.errorHandlingCallback (com.mongodb.internal.async.ErrorHandlingResultCallback.errorHandlingCallback)7 SingleResultCallback (com.mongodb.internal.async.SingleResultCallback)7 AsyncCallbackSupplier (com.mongodb.internal.async.function.AsyncCallbackSupplier)7 AsyncConnection (com.mongodb.internal.connection.AsyncConnection)7 Connection (com.mongodb.internal.connection.Connection)7 LOGGER (com.mongodb.internal.operation.OperationHelper.LOGGER)7 OperationHelper.withAsyncSourceAndConnection (com.mongodb.internal.operation.OperationHelper.withAsyncSourceAndConnection)7 OperationHelper.withSourceAndConnection (com.mongodb.internal.operation.OperationHelper.withSourceAndConnection)7 Supplier (java.util.function.Supplier)7 BsonDocument (org.bson.BsonDocument)7 ReadPreference (com.mongodb.ReadPreference)6 ReadPreference.primary (com.mongodb.ReadPreference.primary)6 ServerDescription (com.mongodb.connection.ServerDescription)6 AsyncBatchCursor (com.mongodb.internal.async.AsyncBatchCursor)6 AsyncConnectionSource (com.mongodb.internal.binding.AsyncConnectionSource)6 AsyncReadBinding (com.mongodb.internal.binding.AsyncReadBinding)6