Пример #1
0
        /// <summary>
        /// Creates and initializes a retryable read operation context.
        /// </summary>
        /// <param name="binding">The binding.</param>
        /// <param name="retryRequested">if set to <c>true</c> [retry requested].</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A retryable read context.</returns>
        public static async Task <RetryableReadContext> CreateAsync(IReadBinding binding, bool retryRequested, CancellationToken cancellationToken)
        {
            var context = new RetryableReadContext(binding, retryRequested);

            try
            {
                await context.InitializeAsync(cancellationToken).ConfigureAwait(false);

                if (ChannelPinningHelper.PinChannelSourceAndChannelIfRequired(
                        context.ChannelSource,
                        context.Channel,
                        context.Binding.Session,
                        out var pinnedChannelSource,
                        out var pinnedChannel))
                {
                    context.ReplaceChannelSource(pinnedChannelSource);
                    context.ReplaceChannel(pinnedChannel);
                }
                return(context);
            }
            catch
            {
                context.Dispose();
                throw;
            }
        }
Пример #2
0
        public static bool ShouldConnectionAcquireBeRetried(RetryableReadContext context, Exception ex)
        {
            // According the spec error during handshake should be handle according to RetryableReads logic
            var innerException = ex is MongoAuthenticationException mongoAuthenticationException ? mongoAuthenticationException.InnerException : ex;

            return(context.RetryRequested && !context.Binding.Session.IsInTransaction && RetryabilityHelper.IsRetryableReadException(innerException));
        }
 public static async Task <TResult> ExecuteAsync <TResult>(IRetryableReadOperation <TResult> operation, IReadBinding binding, bool retryRequested, CancellationToken cancellationToken)
 {
     using (var context = await RetryableReadContext.CreateAsync(binding, retryRequested, cancellationToken).ConfigureAwait(false))
     {
         return(await ExecuteAsync(operation, context, cancellationToken).ConfigureAwait(false));
     }
 }
 // public static methods
 public static TResult Execute <TResult>(IRetryableReadOperation <TResult> operation, IReadBinding binding, bool retryRequested, CancellationToken cancellationToken)
 {
     using (var context = RetryableReadContext.Create(binding, retryRequested, cancellationToken))
     {
         return(Execute(operation, context, cancellationToken));
     }
 }
        /// <inheritdoc/>
        public IAsyncCursor <BsonDocument> Execute(RetryableReadContext context, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(context, nameof(context));

            var operation = CreateOperation();

            return(operation.Execute(context, cancellationToken));
        }
        /// <inheritdoc/>
        public async Task <IAsyncCursor <BsonDocument> > ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(context, nameof(context));

            var operation = CreateOperation();

            return(await operation.ExecuteAsync(context, cancellationToken).ConfigureAwait(false));
        }
        /// <inheritdoc/>
        public async Task <IAsyncCursor <TDocument> > ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(context, nameof(context));

            var operation = CreateOperation(context.Channel.ConnectionDescription.ServerVersion);

            return(await operation.ExecuteAsync(context, cancellationToken).ConfigureAwait(false));
        }
        /// <inheritdoc/>
        public IAsyncCursor <TDocument> Execute(RetryableReadContext context, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(context, nameof(context));

            var operation = CreateOperation(context.Channel.ConnectionDescription.ServerVersion);

            return(operation.Execute(context, cancellationToken));
        }
Пример #9
0
        /// <inheritdoc/>
        public async Task <IAsyncCursor <TDocument> > ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(binding, nameof(binding));

            using (var context = await RetryableReadContext.CreateAsync(binding, retryRequested: false, cancellationToken).ConfigureAwait(false))
            {
                return(await ExecuteAsync(context, cancellationToken).ConfigureAwait(false));
            }
        }
Пример #10
0
        /// <inheritdoc/>
        public IAsyncCursor <TDocument> Execute(IReadBinding binding, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(binding, nameof(binding));

            using (var context = RetryableReadContext.Create(binding, retryRequested: false, cancellationToken))
            {
                return(Execute(context, cancellationToken));
            }
        }
        /// <inheritdoc/>
        public IAsyncCursor <BsonDocument> Execute(RetryableReadContext context, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(context, nameof(context));

            using (EventContext.BeginOperation())
            {
                var operation = CreateOperation();
                var result    = operation.Execute(context, cancellationToken);
                return(CreateCursor(context.ChannelSource, operation.Command, result));
            }
        }
Пример #12
0
        /// <inheritdoc/>
        public IAsyncCursor <BsonDocument> Execute(RetryableReadContext context, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(context, nameof(context));

            using (EventContext.BeginOperation())
            {
                var operation = CreateOperation();
                var cursor    = operation.Execute(context, cancellationToken);
                return(new BatchTransformingAsyncCursor <BsonDocument, BsonDocument>(cursor, NormalizeQueryResponse));
            }
        }
Пример #13
0
        // public static methods
        /// <summary>
        /// Creates and initializes a retryable read operation context.
        /// </summary>
        /// <param name="binding">The binding.</param>
        /// <param name="retryRequested">if set to <c>true</c> [retry requested].</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A retryable read context.</returns>
        public static RetryableReadContext Create(IReadBinding binding, bool retryRequested, CancellationToken cancellationToken)
        {
            var context = new RetryableReadContext(binding, retryRequested);

            try
            {
                context.Initialize(cancellationToken);
                return(context);
            }
            catch
            {
                context.Dispose();
                throw;
            }
        }
Пример #14
0
        /// <inheritdoc/>
        public IAsyncCursor <TDocument> Execute(RetryableReadContext context, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(context, nameof(context));

            using (EventContext.BeginOperation())
                using (EventContext.BeginFind(_batchSize, _limit))
                {
                    var readPreference    = context.Binding.ReadPreference;
                    var serverDescription = context.ChannelSource.ServerDescription;
                    var wrappedQuery      = CreateWrappedQuery(serverDescription.Type, readPreference, out var secondaryOk);

                    var batch = ExecuteProtocol(context.Channel, wrappedQuery, secondaryOk, cancellationToken);
                    return(CreateCursor(context.ChannelSource, wrappedQuery, batch));
                }
        }
Пример #15
0
        /// <summary>
        /// Creates and initializes a retryable read operation context.
        /// </summary>
        /// <param name="binding">The binding.</param>
        /// <param name="retryRequested">if set to <c>true</c> [retry requested].</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A retryable read context.</returns>
        public static async Task <RetryableReadContext> CreateAsync(IReadBinding binding, bool retryRequested, CancellationToken cancellationToken)
        {
            var context = new RetryableReadContext(binding, retryRequested);

            try
            {
                await context.InitializeAsync(cancellationToken).ConfigureAwait(false);

                return(context);
            }
            catch
            {
                context.Dispose();
                throw;
            }
        }
Пример #16
0
        /// <inheritdoc/>
        public async Task <IAsyncCursor <TDocument> > ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(context, nameof(context));

            using (EventContext.BeginOperation())
                using (EventContext.BeginFind(_batchSize, _limit))
                {
                    var readPreference    = context.Binding.ReadPreference;
                    var serverDescription = context.ChannelSource.ServerDescription;
                    var wrappedQuery      = CreateWrappedQuery(serverDescription.Type, readPreference);
                    var slaveOk           = readPreference != null && readPreference.ReadPreferenceMode != ReadPreferenceMode.Primary;

                    var batch = await ExecuteProtocolAsync(context.Channel, wrappedQuery, slaveOk, cancellationToken).ConfigureAwait(false);

                    return(CreateCursor(context.ChannelSource, wrappedQuery, batch));
                }
        }
Пример #17
0
        // public static methods
        /// <summary>
        /// Creates and initializes a retryable read operation context.
        /// </summary>
        /// <param name="binding">The binding.</param>
        /// <param name="retryRequested">if set to <c>true</c> [retry requested].</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A retryable read context.</returns>
        public static RetryableReadContext Create(IReadBinding binding, bool retryRequested, CancellationToken cancellationToken)
        {
            var context = new RetryableReadContext(binding, retryRequested);

            try
            {
                context.Initialize(cancellationToken);

                ChannelPinningHelper.PinChannellIfRequired(
                    context.ChannelSource,
                    context.Channel,
                    context.Binding.Session);

                return(context);
            }
            catch
            {
                context.Dispose();
                throw;
            }
        }
        public static async Task <TResult> ExecuteAsync <TResult>(IRetryableReadOperation <TResult> operation, RetryableReadContext context, CancellationToken cancellationToken)
        {
            if (!ShouldReadBeRetried(context))
            {
                return(await operation.ExecuteAttemptAsync(context, attempt : 1, transactionNumber : null, cancellationToken).ConfigureAwait(false));
            }

            var       initialServerVersion = context.Channel.ConnectionDescription.ServerVersion;
            Exception originalException;

            try
            {
                return(await operation.ExecuteAttemptAsync(context, attempt : 1, transactionNumber : null, cancellationToken).ConfigureAwait(false));
            }
            catch (Exception ex) when(RetryabilityHelper.IsRetryableReadException(ex))
            {
                originalException = ex;
            }

            try
            {
                context.ReplaceChannelSource(context.Binding.GetReadChannelSource(cancellationToken));
                context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken));
            }
            catch
            {
                throw originalException;
            }

            if (context.Channel.ConnectionDescription.ServerVersion < initialServerVersion)
            {
                throw originalException;
            }

            if (!AreRetryableReadsSupported(context))
            {
                throw originalException;
            }

            try
            {
                return(await operation.ExecuteAttemptAsync(context, attempt : 2, transactionNumber : null, cancellationToken).ConfigureAwait(false));
            }
            catch (Exception ex) when(ShouldThrowOriginalException(ex))
            {
                throw originalException;
            }
        }
        public static TResult Execute <TResult>(IRetryableReadOperation <TResult> operation, RetryableReadContext context, CancellationToken cancellationToken)
        {
            if (!ShouldReadBeRetried(context))
            {
                return(operation.ExecuteAttempt(context, attempt: 1, transactionNumber: null, cancellationToken));
            }

            Exception originalException;

            try
            {
                return(operation.ExecuteAttempt(context, attempt: 1, transactionNumber: null, cancellationToken));
            }
            catch (Exception ex) when(RetryabilityHelper.IsRetryableReadException(ex))
            {
                originalException = ex;
            }

            try
            {
                context.ReplaceChannelSource(context.Binding.GetReadChannelSource(cancellationToken));
                context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken));
            }
            catch
            {
                throw originalException;
            }

            try
            {
                return(operation.ExecuteAttempt(context, attempt: 2, transactionNumber: null, cancellationToken));
            }
            catch (Exception ex) when(ShouldThrowOriginalException(ex))
            {
                throw originalException;
            }
        }
 private static bool ShouldReadBeRetried(RetryableReadContext context)
 {
     return(context.RetryRequested && AreRetryableReadsSupported(context) && !context.Binding.Session.IsInTransaction);
 }
 public static bool ShouldConnectionAcquireBeRetried(RetryableReadContext context, ServerDescription serverDescription)
 {
     return(context.RetryRequested &&
            Feature.RetryableReads.IsSupported(serverDescription.Version) &&
            !context.Binding.Session.IsInTransaction);
 }
 // private static methods
 private static bool AreRetryableReadsSupported(RetryableReadContext context)
 {
     return(Feature.RetryableReads.IsSupported(context.Channel.ConnectionDescription.ServerVersion));
 }