public void IsRetryableReadException_should_return_expected_result_using_code(int code, bool expectedResult) { var exception = CoreExceptionHelper.CreateMongoCommandException(code); var result = RetryabilityHelper.IsRetryableReadException(exception); result.Should().Be(expectedResult); }
public void IsRetryableReadException_should_return_expected_result_using_exception_type(Type exceptionType, bool expectedResult) { var exception = CoreExceptionHelper.CreateException(exceptionType); var result = RetryabilityHelper.IsRetryableReadException(exception); result.Should().Be(expectedResult); }
public static bool ShouldConnectionAcquireBeRetried(RetryableWriteContext context, ServerDescription serverDescription, Exception exception) { var innerException = exception is MongoAuthenticationException mongoAuthenticationException ? mongoAuthenticationException.InnerException : exception; // According the spec error during handshake should be handle according to RetryableReads logic return(context.RetryRequested && AreRetryableWritesSupported(serverDescription) && context.Binding.Session.Id != null && !context.Binding.Session.IsInTransaction && RetryabilityHelper.IsRetryableReadException(innerException)); }
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; } }
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)); }