示例#1
0
        public ExecutionState(StorageCommandBase <T> cmd, IRetryPolicy policy, OperationContext operationContext)
        {
            this.Cmd         = cmd;
            this.RetryPolicy = policy != null?policy.CreateInstance() : new NoRetry();

            this.OperationContext = operationContext ?? new OperationContext();

#if RT
            if (this.OperationContext.StartTime == DateTimeOffset.MinValue)
            {
                this.OperationContext.StartTime = DateTimeOffset.Now;
            }
#else
            if (this.OperationContext.StartTime == DateTime.MinValue)
            {
                this.OperationContext.StartTime = DateTime.Now;
            }
#endif
            if (!this.OperationContext.OperationExpiryTime.HasValue && cmd != null && cmd.ClientMaxTimeout.HasValue)
            {
                this.OperationExpiryTime = DateTime.Now + cmd.ClientMaxTimeout.Value;
            }
            else if (this.OperationContext.OperationExpiryTime.HasValue)
            {
                // Override timeout for complex actions
#if RT
                this.OperationExpiryTime = this.OperationContext.OperationExpiryTime.Value.UtcDateTime;
#else
                this.OperationExpiryTime = this.OperationContext.OperationExpiryTime.Value;
#endif
            }
        }
示例#2
0
        private async Task <BarionOperationResult> SendWithRetry(BarionOperation operation, CancellationToken cancellationToken)
        {
            var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

            SetTimeout(linkedCts);

            var      shouldRetry         = false;
            uint     currentRetryCount   = 0;
            TimeSpan retryInterval       = TimeSpan.Zero;
            BarionOperationResult result = null;

            do
            {
                var message = PrepareHttpRequestMessage(operation);

                try
                {
                    var responseMessage = await _httpClient.SendAsync(message, linkedCts.Token);

                    result = await CreateResultFromResponseMessage(responseMessage, operation);

                    if (!result.IsOperationSuccessful)
                    {
                        shouldRetry = _retryPolicy.CreateInstance().ShouldRetry(currentRetryCount, responseMessage.StatusCode, out retryInterval);
                    }
                }
                catch (Exception ex)
                {
                    shouldRetry = _retryPolicy.CreateInstance().ShouldRetry(currentRetryCount, ex, out retryInterval);

                    if (!shouldRetry)
                    {
                        throw;
                    }
                }

                if (shouldRetry)
                {
                    await Task.Delay(retryInterval);

                    currentRetryCount++;
                }
            } while (shouldRetry && !linkedCts.IsCancellationRequested);

            return(result);
        }
示例#3
0
        public ExecutionState(StorageCommandBase <T> cmd, IRetryPolicy policy, OperationContext operationContext)
        {
            this.Cmd         = cmd;
            this.RetryPolicy = policy != null?policy.CreateInstance() : new NoRetry();

            this.OperationContext = operationContext ?? new OperationContext();
            this.InitializeLocation();

            if (this.OperationContext.StartTime == DateTime.MinValue)
            {
                this.OperationContext.StartTime = DateTime.Now;
            }
        }
        public ExecutionState(StorageCommandBase <T> cmd, IRetryPolicy policy, OperationContext operationContext, AsyncCallback callback, object asyncState)
            : base(callback, asyncState)
        {
            this.Cmd         = cmd;
            this.RetryPolicy = policy != null?policy.CreateInstance() : new NoRetry();

            this.OperationContext = operationContext ?? new OperationContext();

            if (this.OperationContext.StartTime == DateTime.MinValue)
            {
                this.OperationContext.StartTime = DateTime.Now;
            }
        }
示例#5
0
        public ExecutionState(StorageCommandBase <T> cmd, IRetryPolicy policy, OperationContext operationContext, AsyncCallback callback, object asyncState)
            : base(callback, asyncState)
        {
            this.Cmd              = cmd;
            this.RetryPolicy      = policy.CreateInstance();
            this.OperationContext = operationContext ?? new OperationContext();

            if (!this.OperationContext.OperationExpiryTime.HasValue && cmd != null && cmd.ClientMaxTimeout.HasValue)
            {
                this.OperationExpiryTime = DateTime.Now + cmd.ClientMaxTimeout.Value;
            }
            else if (this.OperationContext.OperationExpiryTime.HasValue)
            {
                // Override timeout for complex actions
                this.OperationExpiryTime = this.OperationContext.OperationExpiryTime.Value;
            }
        }
示例#6
0
    /// <summary>
    /// Processes an action with this retry policy.
    /// </summary>
    /// <param name="policy">The retry policy.</param>
    /// <param name="action">The async action which will return a result to process.</param>
    /// <param name="needThrow">A handler to check if need throw the exception without retry.</param>
    /// <param name="cancellationToken">The optional cancellation token.</param>
    /// <returns>The processing retry result.</returns>
    public static async Task <RetryResult <T> > ProcessAsync <T>(this IRetryPolicy policy, Func <CancellationToken, Task <T> > action, Func <Exception, Exception> needThrow, CancellationToken cancellationToken = default)
    {
        var result = new RetryResult <T>();

        if (action == null)
        {
            return(result);
        }
        if (needThrow == null)
        {
            needThrow = ex => ex;
        }
        var retry = policy?.CreateInstance() ?? new InternalRetryInstance();

        while (true)
        {
            try
            {
                cancellationToken.ThrowIfCancellationRequested();
                var r = await action(cancellationToken);

                result.Success(r);
                return(result);
            }
            catch (Exception ex)
            {
                result.Fail(ex);
                ex = needThrow(ex);
                if (ex != null)
                {
                    throw ex;
                }
            }

            var span = retry.Next();
            if (!span.HasValue)
            {
                result.End();
                return(result);
            }

            await Task.Delay(span.Value, cancellationToken);
        }
    }
        public ExecutionState(StorageCommandBase <T> cmd, IRetryPolicy policy, OperationContext operationContext)
        {
            this.Cmd         = cmd;
            this.RetryPolicy = policy != null?policy.CreateInstance() : new NoRetry();

            this.OperationContext = operationContext ?? new OperationContext();

#if WINDOWS_RT
            if (this.OperationContext.StartTime == DateTimeOffset.MinValue)
            {
                this.OperationContext.StartTime = DateTimeOffset.Now;
            }
#else
            if (this.OperationContext.StartTime == DateTime.MinValue)
            {
                this.OperationContext.StartTime = DateTime.Now;
            }
#endif
        }
示例#8
0
        public ExecutionState(RESTCommand <T> cmd, IRetryPolicy policy, OperationContext operationContext)
        {
            Cmd = cmd;
            object retryPolicy2;

            if (policy == null)
            {
                IRetryPolicy retryPolicy = new NoRetry();
                retryPolicy2 = retryPolicy;
            }
            else
            {
                retryPolicy2 = policy.CreateInstance();
            }
            RetryPolicy      = (IRetryPolicy)retryPolicy2;
            OperationContext = (operationContext ?? new OperationContext());
            InitializeLocation();
            if (OperationContext.StartTime == DateTimeOffset.MinValue)
            {
                OperationContext.StartTime = DateTimeOffset.Now;
            }
        }
示例#9
0
        public ExecutionState(StorageCommandBase <T> cmd, IRetryPolicy policy, OperationContext operationContext)
        {
            this.Cmd         = cmd;
            this.RetryPolicy = policy != null?policy.CreateInstance() : new NoRetry();

            this.OperationContext = operationContext ?? new OperationContext();
#if !(WINDOWS_RT || NETCORE)
            this.CancellationTokenSource = new CancellationTokenSource();
#endif
            this.InitializeLocation();

#if WINDOWS_RT || NETCORE
            if (this.OperationContext.StartTime == DateTimeOffset.MinValue)
            {
                this.OperationContext.StartTime = DateTimeOffset.Now;
            }
#else
            if (this.OperationContext.StartTime == DateTime.MinValue)
            {
                this.OperationContext.StartTime = DateTime.Now;
            }
#endif
        }
示例#10
0
 public IRetryPolicy CreateInstance()
 {
     return(new DontRetryOnNotModifiedPolicy(_innerPolicy.CreateInstance()));
 }
示例#11
0
        /// <summary>
        /// Executes the specified operation with retries.
        /// </summary>
        /// <param name="retryPolicy">The policy that determines the retry logic.</param>
        /// <param name="func">The operation to be executed with retries.</param>
        /// <param name="actionToExecuteBeforeRetry">The action be executed before each retry attempt.</param>
        /// <param name="ignoreNonFatalExceptions">True if non-critical exceptions should be ignored, false otherwise.</param>
        /// <returns></returns>
        private static bool ExecuteInternal(IRetryPolicy retryPolicy, Func <int, bool> func, Action actionToExecuteBeforeRetry, bool ignoreNonFatalExceptions)
        {
            if (retryPolicy == null)
            {
                throw new ArgumentNullException("retryPolicy");
            }

            if (func == null)
            {
                throw new ArgumentNullException("func");
            }

            if (actionToExecuteBeforeRetry == null)
            {
                throw new ArgumentNullException("actionToExecuteBeforeRetry");
            }

            // Clone the retry policy to prevent reusing the same instance.
            IRetryPolicy internalRetryPolicy = retryPolicy.CreateInstance();

            if (internalRetryPolicy == null)
            {
                throw new InvalidOperationException("The CreateInstance() for the retrypolicy returned null.");
            }

            int iterationCount = 0;

            while (true)
            {
                try
                {
                    if (func(iterationCount))
                    {
                        return(true);
                    }

                    if (!internalRetryPolicy.ShouldRetry)
                    {
                        return(false);
                    }

                    actionToExecuteBeforeRetry();

                    Thread.Sleep(internalRetryPolicy.WaitTimeBeforeNextRetry);
                    iterationCount++;
                }
                catch (Exception ex)
                {
                    // Always re-throw fatal exceptions.
                    if (ex.IsFatal())
                    {
                        throw;
                    }

                    // Re-throw non-fatal exceptions if specified by caller.
                    if (!ignoreNonFatalExceptions)
                    {
                        throw;
                    }
                }
            }
        }