protected virtual async Task <AsyncOperationResult <T> > TryOperationAsync <T>(Func <OperationMetadata, IRequestTimeMetric, Task <T> > operation, OperationMetadata operationMetadata,
                                                                                       OperationMetadata primaryOperationMetadata, IRequestTimeMetric requestTimeMetric, bool avoidThrowing, CancellationToken cancellationToken = default(CancellationToken))
        {
            var  tryWithPrimaryCredentials = FailureCounters.IsFirstFailure(operationMetadata.Url) && primaryOperationMetadata != null;
            bool shouldTryAgain            = false;

            try
            {
                cancellationToken.ThrowCancellationIfNotDefault(); //canceling the task here potentially will stop the recursion
                var result = await operation(tryWithPrimaryCredentials?new OperationMetadata(operationMetadata.Url, primaryOperationMetadata.Credentials, primaryOperationMetadata.ClusterInformation) : operationMetadata, requestTimeMetric).ConfigureAwait(false);

                FailureCounters.ResetFailureCount(operationMetadata.Url);
                return(new AsyncOperationResult <T>
                {
                    Result = result,
                    Success = true
                });
            }
            catch (Exception e)
            {
                var ae = e as AggregateException;
                var singleInnerException = ae.ExtractSingleInnerException();
                ErrorResponseException errorResponseException;
                if (ae != null)
                {
                    errorResponseException = singleInnerException as ErrorResponseException;
                }
                else
                {
                    errorResponseException = e as ErrorResponseException;
                }
                if (tryWithPrimaryCredentials && operationMetadata.Credentials.HasCredentials() && errorResponseException != null)
                {
                    FailureCounters.IncrementFailureCount(operationMetadata.Url);

                    if (errorResponseException.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        shouldTryAgain = true;
                    }
                }

                if (shouldTryAgain == false)
                {
                    if (avoidThrowing == false)
                    {
                        var timeoutException = singleInnerException as TimeoutException;
                        if (timeoutException != null)
                        {
                            throw timeoutException;
                        }

                        throw;
                    }

                    bool wasTimeout;
                    var  isServerDown = HttpConnectionHelper.IsServerDown(e, out wasTimeout);

                    if (e.Data.Contains(Constants.RequestFailedExceptionMarker) && isServerDown)
                    {
                        return(new AsyncOperationResult <T>
                        {
                            Success = false,
                            WasTimeout = wasTimeout,
                            Error = e
                        });
                    }

                    if (isServerDown)
                    {
                        return(new AsyncOperationResult <T>
                        {
                            Success = false,
                            WasTimeout = wasTimeout,
                            Error = e
                        });
                    }

                    if (errorResponseException != null)
                    {
                        throw errorResponseException;
                    }

                    throw;
                }
            }
            return(await TryOperationAsync(operation, operationMetadata, primaryOperationMetadata, requestTimeMetric, avoidThrowing, cancellationToken).ConfigureAwait(false));
        }
Esempio n. 2
0
 internal ReplicationDocumentWithClusterInformation DirectGetReplicationDestinations(OperationMetadata operationMetadata, IRequestTimeMetric requestTimeMetric)
 {
     return(AsyncHelpers.RunSync(() => asyncServerClient.DirectGetReplicationDestinationsAsync(operationMetadata, requestTimeMetric)));
 }
Esempio n. 3
0
        internal HttpJsonRequest(
            CreateHttpJsonRequestParams requestParams,
            HttpJsonRequestFactory factory)
        {
            _credentials        = requestParams.DisableAuthentication == false ? requestParams.Credentials : null;
            disabledAuthRetries = requestParams.DisableAuthentication;

            Url    = requestParams.Url;
            Method = requestParams.Method;

            if (requestParams.Timeout.HasValue)
            {
                Timeout = requestParams.Timeout.Value;
            }
            else
            {
                Timeout = TimeSpan.FromSeconds(100); // default HttpClient timeout
#if DEBUG
                if (Debugger.IsAttached)
                {
                    Timeout = TimeSpan.FromMinutes(5);
                }
#endif
            }

            this.factory      = factory;
            owner             = requestParams.Owner;
            conventions       = requestParams.Convention;
            requestTimeMetric = requestParams.RequestTimeMetric;

            recreateHandler = factory.httpMessageHandler ?? (
                () =>
            {
                var useDefaultCredentials = _credentials != null && _credentials.HasCredentials() == false;
                ICredentials credentialsToUse = null;
                if (_credentials != null)
                {
                    var networkCredentials = _credentials.Credentials as NetworkCredential;
                    if (networkCredentials != null && factory.authenticationScheme != null)
                    {
                        var credentialCache = new CredentialCache();
                        var uri = new Uri(requestParams.Url);
                        credentialCache.Add(new Uri(string.Format("{0}://{1}:{2}/", uri.Scheme, uri.Host, uri.Port)), factory.authenticationScheme, networkCredentials);

                        credentialsToUse = credentialCache;
                    }
                    else
                    {
                        credentialsToUse = _credentials.Credentials;
                    }
                }
#if !DNXCORE50
                var handler = new WebRequestHandler
                {
                    AllowAutoRedirect = false,
                    UseDefaultCredentials = useDefaultCredentials,
                    Credentials = credentialsToUse
                };
#else
                var handler = new HttpClientHandler
                {
                    AllowAutoRedirect = false,
                    UseDefaultCredentials = useDefaultCredentials,
                    Credentials = credentialsToUse
                };
#endif
                return(handler);
            }
                );

            httpClient = factory.httpClientCache.GetClient(Timeout, _credentials, recreateHandler);

            if (factory.DisableRequestCompression == false && requestParams.DisableRequestCompression == false)
            {
                if (Method == HttpMethods.Post || Method == HttpMethods.Put || Method == HttpMethods.Patch || Method == HttpMethods.Eval)
                {
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Encoding", "gzip");
                    httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");
                }

                if (factory.acceptGzipContent)
                {
                    httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
                }
            }

            headers.Add("Raven-Client-Version", ClientVersion);
            WriteMetadata(requestParams.Metadata);
            requestParams.UpdateHeaders(headers);
        }
Esempio n. 4
0
 public string DirectPutIndex(string name, OperationMetadata operationMetadata, IRequestTimeMetric requestTimeMetric, bool overwrite,
                              IndexDefinition definition)
 {
     return(AsyncHelpers.RunSync(() => asyncServerClient.DirectPutIndexAsync(name, definition, overwrite, operationMetadata, requestTimeMetric)));
 }
Esempio n. 5
0
 public DecreasingTimeMetric(IRequestTimeMetric requestTimeMetric)
 {
     this.requestTimeMetric = requestTimeMetric;
 }