Search in sources :

Example 11 with ConnectionDescription

use of com.mongodb.connection.ConnectionDescription 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)

Example 12 with ConnectionDescription

use of com.mongodb.connection.ConnectionDescription in project brave by openzipkin.

the class TraceMongoCommandListener method commandStarted.

/**
 * Uses {@link ThreadLocalSpan} as there's no attribute namespace shared between callbacks, but
 * all callbacks happen on the same thread.
 */
@Override
public void commandStarted(CommandStartedEvent event) {
    String databaseName = event.getDatabaseName();
    // don't trace commands like "endSessions"
    if ("admin".equals(databaseName))
        return;
    Span span = threadLocalSpan.next();
    if (span == null || span.isNoop())
        return;
    String commandName = event.getCommandName();
    BsonDocument command = event.getCommand();
    String collectionName = getCollectionName(command, commandName);
    span.name(getSpanName(commandName, collectionName)).kind(CLIENT).remoteServiceName("mongodb-" + databaseName).tag("mongodb.command", commandName);
    if (collectionName != null) {
        span.tag("mongodb.collection", collectionName);
    }
    ConnectionDescription connectionDescription = event.getConnectionDescription();
    if (connectionDescription != null) {
        ConnectionId connectionId = connectionDescription.getConnectionId();
        if (connectionId != null) {
            span.tag("mongodb.cluster_id", connectionId.getServerId().getClusterId().getValue());
        }
        try {
            InetSocketAddress socketAddress = connectionDescription.getServerAddress().getSocketAddress();
            span.remoteIpAndPort(socketAddress.getAddress().getHostAddress(), socketAddress.getPort());
        } catch (MongoSocketException ignored) {
        }
    }
    span.start();
}
Also used : ConnectionDescription(com.mongodb.connection.ConnectionDescription) ConnectionId(com.mongodb.connection.ConnectionId) BsonDocument(org.bson.BsonDocument) InetSocketAddress(java.net.InetSocketAddress) MongoSocketException(com.mongodb.MongoSocketException) Span(brave.Span) ThreadLocalSpan(brave.propagation.ThreadLocalSpan)

Aggregations

ConnectionDescription (com.mongodb.connection.ConnectionDescription)12 ServerAddress (com.mongodb.ServerAddress)6 ClusterId (com.mongodb.connection.ClusterId)6 ConnectionId (com.mongodb.connection.ConnectionId)6 ServerId (com.mongodb.connection.ServerId)6 Before (org.junit.Before)5 MongoException (com.mongodb.MongoException)2 WriteConcern (com.mongodb.WriteConcern)2 Assertions (com.mongodb.assertions.Assertions)2 BulkWriteResult (com.mongodb.bulk.BulkWriteResult)2 SingleResultCallback (com.mongodb.internal.async.SingleResultCallback)2 RetryState (com.mongodb.internal.async.function.RetryState)2 DescriptionHelper.createConnectionDescription (com.mongodb.internal.connection.DescriptionHelper.createConnectionDescription)2 MongoWriteConcernWithResponseException (com.mongodb.internal.connection.MongoWriteConcernWithResponseException)2 Span (brave.Span)1 ThreadLocalSpan (brave.propagation.ThreadLocalSpan)1 MongoBulkWriteException (com.mongodb.MongoBulkWriteException)1 MongoClientException (com.mongodb.MongoClientException)1 MongoConnectionPoolClearedException (com.mongodb.MongoConnectionPoolClearedException)1 MongoCredential (com.mongodb.MongoCredential)1