コード例 #1
0
 /// <summary>
 /// This will execute a DocumentDB client method for you while handling retriable errors such as "too many requests".
 ///
 /// The caller must explicitly wrap the call they want to make in a lambda.  This is so that WithRetry can
 /// execute the lambda in order to ask for the task multiple times instead of getting an instance created at
 /// WithRetry method invocation time.
 ///
 /// Example: "ExecuteResultWithRetry(() => YourCallHere(arguments, will, be, closured));"
 /// </summary>
 /// <param name="action"></param>
 /// <param name="resourceResponseHandler"></param>
 /// <param name="maxRetries"></param>
 /// <param name="maxTime"></param>
 /// <param name="shouldRetry"></param>
 /// <returns></returns>
 public static async Task ExecuteResultWithRetry(Func <Task> action, ResourceResponseHandler resourceResponseHandler, int maxRetries, TimeSpan maxTime, ShouldRetry shouldRetry)
 {
     // just wrap it in a task and call the main WithRetry method
     await ExecuteResultWithRetry <int>(async() => { await action(); return(0); }, resourceResponseHandler, maxRetries, maxTime, shouldRetry);
 }
コード例 #2
0
        /// <summary>
        /// This will execute a DocumentDB client method for you while handling retriable errors such as "too many requests".
        ///
        /// The caller must explicitly wrap the async call they want to make in a lambda.  This is so that WithRetry can
        /// execute the lambda in order to ask for the task multiple times instead of getting an instance created at
        /// WithRetry method invocation time.
        ///
        /// Example: "ExecuteResultWithRetry(() => YourCallHere(arguments, will, be, closured));"
        /// </summary>
        /// <typeparam name="R"></typeparam>
        /// <param name="action"></param>
        /// <param name="resourceResponseHandler"></param>
        /// <param name="maxRetries"></param>
        /// <param name="maxTime"></param>
        /// <param name="shouldRetry"></param>
        /// <returns></returns>
        public static async Task <R> ExecuteResultWithRetry <R>(Func <Task <R> > action, ResourceResponseHandler resourceResponseHandler, int maxRetries, TimeSpan maxTime, ShouldRetry shouldRetry)
        {
            // time the execution
            Stopwatch sw = new Stopwatch();

            sw.Start();

            // count the retries
            int retries = 0;

            // remember the last exception
            Exception lastEx;

            while (true)
            {
                TimeSpan retryDelay = TimeSpan.Zero;

                try
                {
                    var result = await action();

                    if (result is IResourceResponseBase)
                    {
                        resourceResponseHandler(result as IResourceResponseBase);
                    }

                    return(result);
                }
                catch (Exception clientException)
                {
                    lastEx = clientException;

                    try
                    {
                        retryDelay = shouldRetry(null, clientException);
                    }
                    catch (DocumentDbConflictResponse)
                    {
                        // conflict response was already handled properly internally to the ShouldRetry handler
                        throw;
                    }
                    catch (DocumentDbUnexpectedResponse)
                    {
                        // unexpected response was already handled properly internally to the ShouldRetry handler
                        throw;
                    }
                    catch (DocumentDbNonRetriableResponse)
                    {
                        // non-retriable response was already handled properly internally to the ShouldRetry handler
                        throw;
                    }
                    catch (Exception ex)
                    {
                        // someone gave us a bad ShouldRetry handler
                        throw new DocumentDbRetryHandlerError("The ShouldRetry handler threw an unexpected exception.", ex);
                    }

                    if (null == retryDelay)
                    {
                        // someone gave us a bad ShouldRetry handler
                        throw new DocumentDbRetryHandlerError("The ShouldRetry handler returned a null delay.", clientException);
                    }
                }

                if (sw.Elapsed > maxTime || retries > maxRetries)
                {
                    throw new DocumentDbRetriesExceeded("Exceeded retry count (" + retries + " of " + maxRetries + ") or time (" + sw.Elapsed + " of " + maxTime + ") limit while retrying operation.", lastEx);
                }

                await Task.Delay(retryDelay);

                retries++;
            }
        }
コード例 #3
0
 /// <summary>
 /// This will execute a DocumentDB client method for you while handling retriable errors such as "too many requests".
 ///
 /// The caller must explicitly wrap the call they want to make in a lambda.  This is so that WithRetry can
 /// execute the lambda in order to ask for the task multiple times instead of getting an instance created at
 /// WithRetry method invocation time.
 ///
 /// Example: "ExecuteResultWithRetry(() => YourCallHere(arguments, will, be, closured));"
 /// </summary>
 /// <typeparam name="R"></typeparam>
 /// <param name="action"></param>
 /// <param name="resourceResponseHandler"></param>
 /// <param name="maxRetries"></param>
 /// <param name="maxTime"></param>
 /// <param name="shouldRetry"></param>
 /// <returns></returns>
 public static async Task <R> ExecuteResultWithRetry <R>(Func <R> action, ResourceResponseHandler resourceResponseHandler, int maxRetries, TimeSpan maxTime, ShouldRetry shouldRetry)
 {
     // just wrap it in a task and call the main WithRetry method
     // the call to Task.Run must itself be closured because it takes a param
     return(await ExecuteResultWithRetry <R>(() => Task <R> .Run(action), resourceResponseHandler, maxRetries, maxTime, shouldRetry));
 }