Exemplo n.º 1
0
        /// <summary>
        /// Translates the data service client exception.
        /// </summary>
        /// <param name="e">The exception.</param>
        /// <returns>The translated exception.</returns>
        internal static Exception TranslateDataServiceClientException(InvalidOperationException e)
        {
            var dsce = CommonUtils.FindInnerDataServiceClientException(e);

            if (dsce == null)
            {
                return(e);
            }

            return(TranslateFromHttpStatus(
                       (HttpStatusCode)dsce.StatusCode,
                       null,
                       GetExtendedErrorFromXmlMessage(dsce.Message),
                       e));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Executes the segmented impl.
        /// </summary>
        /// <param name="continuationToken">The continuation token.</param>
        /// <param name="setResult">The set result.</param>
        /// <returns>A <see cref="TaskSequence"/> that executes the query and returns the first segment of results.</returns>
        internal TaskSequence ExecuteSegmentedImpl(ResultContinuation continuationToken, Action <ResultSegment <TElement> > setResult)
        {
            var localQuery = this.query;

            localQuery = RewriteQueryForTakeCount(localQuery, this.pagination);

            localQuery = ApplyContinuationToQuery(continuationToken, localQuery);

            var requestTask = localQuery.ExecuteAsync();

            yield return(requestTask);

            try
            {
                var responseResult = requestTask.Result;
                var response       = responseResult as QueryOperationResponse;

                ResultContinuation newContinuationToken = this.GetTableContinuationFromResponse(response);

                List <TElement> listResult = new List <TElement>(responseResult.ToList());

                ResultSegment.CreateResultSegment <TElement>(
                    setResult,
                    listResult,
                    newContinuationToken,
                    this.pagination,
                    this.RetryPolicy,
                    (scratch, continuationArg, setResultInnerArg) => this.ExecuteSegmentedImpl(continuationArg, setResultInnerArg));
            }
            catch (InvalidOperationException ex)
            {
                var dsce = CommonUtils.FindInnerDataServiceClientException(ex);

                if (dsce == null)
                {
                    throw;
                }

                if ((HttpStatusCode)dsce.StatusCode == HttpStatusCode.NotFound)
                {
                    setResult(new ResultSegment <TElement>(new List <TElement>(), false, null, null));
                }

                throw;
            }
        }
        /// <summary>
        /// Gets the result or default.
        /// </summary>
        /// <typeparam name="T">The type of the result.</typeparam>
        /// <param name="task">The task to retrieve the result from.</param>
        /// <param name="result">Receives result of the task.</param>
        /// <returns><c>true</c> if the result was returned; otherwise, <c>false</c>.</returns>
        private static bool GetResultOrDefault <T>(Task <T> task, out T result)
        {
            try
            {
                result = task.Result;

                return(true);
            }
            catch (DataServiceQueryException ex)
            {
                if ((HttpStatusCode)ex.Response.StatusCode == HttpStatusCode.NotFound)
                {
                    result = default(T);

                    return(false);
                }

                throw Utilities.TranslateDataServiceClientException(ex);
            }
            catch (InvalidOperationException ex)
            {
                DataServiceClientException dsce = CommonUtils.FindInnerDataServiceClientException(ex);

                if (dsce != null)
                {
                    if ((HttpStatusCode)dsce.StatusCode == HttpStatusCode.NotFound)
                    {
                        result = default(T);

                        return(false);
                    }
                }

                throw Utilities.TranslateDataServiceClientException(ex);
            }
        }
        /// <summary>
        /// Implementation of the *RequestWithRetry methods.
        /// </summary>
        /// <typeparam name="T">The result type of the task.</typeparam>
        /// <param name="retryOracle">The retry oracle.</param>
        /// <param name="impl">The task implementation.</param>
        /// <param name="setResult">The result report delegate.</param>
        /// <returns>A <see cref="TaskSequence"/> that performs the request with retries.</returns>
        internal static TaskSequence RequestWithRetryImpl <T>(ShouldRetry retryOracle, Func <Action <T>, TaskSequence> impl, Action <T> setResult)
        {
            int  retryCount  = 0;
            bool succeeded   = false;
            bool shouldRetry = false;

            do
            {
                var task = new InvokeTaskSequenceTask <T>(impl);
                yield return(task);

                TimeSpan delay = TimeSpan.FromMilliseconds(-1);

                try
                {
                    var result = task.Result;
                    succeeded = true;
                    setResult(result);
                }
                catch (TimeoutException e)
                {
                    shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false;

                    // We should just throw out the exception if we are not retrying
                    if (!shouldRetry)
                    {
                        throw;
                    }
                }
                catch (StorageServerException e)
                {
                    if (e.StatusCode == HttpStatusCode.NotImplemented || e.StatusCode == HttpStatusCode.HttpVersionNotSupported)
                    {
                        throw;
                    }

                    shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false;

                    // We should just throw out the exception if we are not retrying
                    if (!shouldRetry)
                    {
                        throw;
                    }
                }
                catch (InvalidOperationException e)
                {
                    DataServiceClientException dsce = CommonUtils.FindInnerDataServiceClientException(e);

                    // rethrow 400 class errors immediately as they can't be retried
                    // 501 (Not Implemented) and 505 (HTTP Version Not Supported) shouldn't be retried either.
                    if (dsce != null &&
                        ((dsce.StatusCode >= 400 && dsce.StatusCode < 500) ||
                         dsce.StatusCode == (int)HttpStatusCode.NotImplemented ||
                         dsce.StatusCode == (int)HttpStatusCode.HttpVersionNotSupported))
                    {
                        throw;
                    }

                    // If it is BlobTypeMismatchExceptionMessage, we should throw without retry
                    if (e.Message == SR.BlobTypeMismatchExceptionMessage)
                    {
                        throw;
                    }

                    shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false;

                    // We should just throw out the exception if we are not retrying
                    if (!shouldRetry)
                    {
                        throw;
                    }
                }

                if (!succeeded && shouldRetry && delay > TimeSpan.Zero)
                {
                    using (DelayTask delayTask = new DelayTask(delay))
                    {
                        yield return(delayTask);

                        // Materialize exceptions
                        var scratch = delayTask.Result;
                    }
                }
            }while (!succeeded && shouldRetry);
        }
        /// <summary>
        /// Implementation of the *RequestWithRetry methods.
        /// </summary>
        /// <typeparam name="TResult">The result type of the task.</typeparam>
        /// <param name="retryOracle">The retry oracle.</param>
        /// <param name="syncTask">The task implementation.</param>
        /// <returns>A <see cref="TaskSequence"/> that performs the request with retries.</returns>
        internal static TResult RequestWithRetrySyncImpl <TResult>(ShouldRetry retryOracle, SynchronousTask <TResult> syncTask)
        {
            int  retryCount  = 0;
            bool shouldRetry = false;

            do
            {
                TimeSpan delay = TimeSpan.FromMilliseconds(-1);

                try
                {
                    return(syncTask.Execute());
                }
                catch (TimeoutException e)
                {
                    shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false;

                    // We should just throw out the exception if we are not retrying
                    if (!shouldRetry)
                    {
                        throw;
                    }
                }
                catch (StorageServerException e)
                {
                    if (e.StatusCode == HttpStatusCode.NotImplemented || e.StatusCode == HttpStatusCode.HttpVersionNotSupported)
                    {
                        throw;
                    }

                    shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false;

                    // We should just throw out the exception if we are not retrying
                    if (!shouldRetry)
                    {
                        throw;
                    }
                }
                catch (InvalidOperationException e)
                {
                    DataServiceClientException dsce = CommonUtils.FindInnerDataServiceClientException(e);

                    // rethrow 400 class errors immediately as they can't be retried
                    // 501 (Not Implemented) and 505 (HTTP Version Not Supported) shouldn't be retried either.
                    if (dsce != null &&
                        ((dsce.StatusCode >= 400 && dsce.StatusCode < 500) ||
                         dsce.StatusCode == (int)HttpStatusCode.NotImplemented ||
                         dsce.StatusCode == (int)HttpStatusCode.HttpVersionNotSupported))
                    {
                        throw;
                    }

                    // If it is BlobTypeMismatchExceptionMessage, we should throw without retry
                    if (e.Message == SR.BlobTypeMismatchExceptionMessage)
                    {
                        throw;
                    }

                    shouldRetry = retryOracle != null?retryOracle(retryCount ++, e, out delay) : false;

                    // We should just throw out the exception if we are not retrying
                    if (!shouldRetry)
                    {
                        throw;
                    }
                }

                if (shouldRetry && delay > TimeSpan.Zero)
                {
                    Thread.Sleep(delay);
                }
            }while (shouldRetry);

            throw new StorageClientException(
                      StorageErrorCode.None,
                      "Unexpected internal storage client error.",
                      System.Net.HttpStatusCode.Unused,
                      null,
                      null)
                  {
                      HelpLink = "http://go.microsoft.com/fwlink/?LinkID=182765"
                  };
        }