public async static Task <TResult> ExecuteAsync <TResult>(IRetryableWriteOperation <TResult> operation, IWriteBinding binding, bool retryRequested, CancellationToken cancellationToken) { using (var context = await RetryableWriteContext.CreateAsync(binding, retryRequested, cancellationToken).ConfigureAwait(false)) { return(await ExecuteAsync(operation, context, cancellationToken).ConfigureAwait(false)); } }
// public static methods public static TResult Execute <TResult>(IRetryableWriteOperation <TResult> operation, IWriteBinding binding, bool retryRequested, CancellationToken cancellationToken) { using (var context = RetryableWriteContext.Create(binding, retryRequested, cancellationToken)) { return(Execute(operation, context, cancellationToken)); } }
private static bool IsOperationAcknowledged <TResult>(IRetryableWriteOperation <TResult> operation) { var writeConcern = operation.WriteConcern; return (writeConcern == null || // null means use server default write concern which implies acknowledged writeConcern.IsAcknowledged); }
public static bool IsOperationAcknowledged(IRetryableWriteOperation <BsonDocument> operation) { var methodInfoDefinition = typeof(RetryableWriteOperationExecutor).GetMethods(BindingFlags.NonPublic | BindingFlags.Static) .Where(m => m.Name == nameof(IsOperationAcknowledged)) .Single(); var methodInfo = methodInfoDefinition.MakeGenericMethod(typeof(BsonDocument)); try { return((bool)methodInfo.Invoke(null, new object[] { operation })); } catch (TargetInvocationException exception) { throw exception.InnerException; } }
public static async Task <TResult> ExecuteAsync <TResult>(IRetryableWriteOperation <TResult> operation, RetryableWriteContext context, CancellationToken cancellationToken) { if (!context.RetryRequested || !AreRetryableWritesSupported(context.Channel.ConnectionDescription)) { return(await operation.ExecuteAttemptAsync(context, 1, null, cancellationToken).ConfigureAwait(false)); } var transactionNumber = context.Binding.Session.AdvanceTransactionNumber(); Exception originalException; try { return(await operation.ExecuteAttemptAsync(context, 1, transactionNumber, cancellationToken).ConfigureAwait(false)); } catch (Exception ex) when(IsRetryableException(ex)) { originalException = ex; } try { context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(cancellationToken).ConfigureAwait(false)); context.ReplaceChannel(await context.ChannelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false)); } catch { throw originalException; } if (!AreRetryableWritesSupported(context.Channel.ConnectionDescription)) { throw originalException; } try { return(await operation.ExecuteAttemptAsync(context, 2, transactionNumber, cancellationToken).ConfigureAwait(false)); } catch (Exception ex) when(ShouldThrowOriginalException(ex)) { throw originalException; } }
public static TResult Execute <TResult>(IRetryableWriteOperation <TResult> operation, RetryableWriteContext context, CancellationToken cancellationToken) { if (!AreRetriesAllowed(operation, context)) { return(operation.ExecuteAttempt(context, 1, null, cancellationToken)); } var transactionNumber = context.Binding.Session.AdvanceTransactionNumber(); Exception originalException; try { return(operation.ExecuteAttempt(context, 1, transactionNumber, cancellationToken)); } catch (Exception ex) when(RetryabilityHelper.IsRetryableWriteException(ex)) { originalException = ex; } try { context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch { throw originalException; } if (!AreRetryableWritesSupported(context.Channel.ConnectionDescription)) { throw originalException; } try { return(operation.ExecuteAttempt(context, 2, transactionNumber, cancellationToken)); } catch (Exception ex) when(ShouldThrowOriginalException(ex)) { throw originalException; } }
// privates static methods private static bool AreRetriesAllowed <TResult>(IRetryableWriteOperation <TResult> operation, RetryableWriteContext context) { return(IsOperationAcknowledged(operation) && DoesContextAllowRetries(context)); }