Exemplo n.º 1
0
        public async Task <AblyResponse> Execute(AblyRequest request)
        {
            var fallbackHosts = Defaults.FallbackHosts.ToList();

            if (CustomHost.IsNotEmpty())
            {
                //The custom host is a fallback host currently in use by the Realtime client.
                //We need to remove it from the fallback hosts
                fallbackHosts.Remove(CustomHost);
            }

            var random = new Random();

            int currentTry      = 0;
            var startTime       = Config.Now();
            var numberOfRetries = Options.HttpMaxRetryCount;
            var host            = CustomHost.IsNotEmpty() ? CustomHost : Options.Host;

            while (currentTry < numberOfRetries)
            {
                var requestTime = Config.Now();
                if ((requestTime - startTime).TotalSeconds >= Options.HttpMaxRetryDuration.TotalSeconds)
                {
                    Logger.Error("Cumulative retry timeout of {0}s was exceeded", Config.CommulativeFailedRequestTimeOutInSeconds);
                    throw new AblyException(
                              new ErrorInfo(string.Format("Commulative retry timeout of {0}s was exceeded.",
                                                          Config.CommulativeFailedRequestTimeOutInSeconds), 500, null));
                }

                Logger.Debug("Executing request: " + request.Url + (currentTry > 0 ? $"try {currentTry}" : ""));
                try
                {
                    var message = GetRequestMessage(request, host);

                    await LogMessage(message);

                    var response = await Client.SendAsync(message, HttpCompletionOption.ResponseContentRead);

                    var ablyResponse = await GetAblyResponse(response);

                    LogResponse(ablyResponse, request.Url);

                    if (response.IsSuccessStatusCode)
                    {
                        return(ablyResponse);
                    }

                    if (IsRetryableResponse(response) && Options.IsDefaultHost)
                    {
                        Logger.Warning("Failed response. Retrying. Returned response with status code: " +
                                       response.StatusCode);

                        if (TryGetNextRandomHost(fallbackHosts, random, out host))
                        {
                            Logger.Debug("Retrying using host {0}", host);
                            currentTry++;
                            continue;
                        }
                    }
                    throw AblyException.FromResponse(ablyResponse);
                }
                catch (HttpRequestException ex) when(IsRetryableError(ex) && Options.IsDefaultHost)
                {
                    Logger.Warning("Error making a connection to Ably servers. Retrying", ex);

                    if (TryGetNextRandomHost(fallbackHosts, random, out host))
                    {
                        Logger.Debug("Retrying using host {0}", host);
                        currentTry++;
                        continue;
                    }
                    throw;
                    //_host = hosts[currentTry - 1];
                }
                catch (TaskCanceledException ex) when(IsRetryableError(ex) && Options.IsDefaultHost)
                {
                    Logger.Warning("Error making a connection to Ably servers. Retrying", ex);
                    if (TryGetNextRandomHost(fallbackHosts, random, out host))
                    {
                        Logger.Debug("Retrying using host {0}", host);
                        currentTry++;
                        continue;
                    }
                    throw;
                }
                catch (HttpRequestException ex) { throw new AblyException(new ErrorInfo("Error executing request", 500), ex); }
                catch (TaskCanceledException ex) { throw new AblyException(new ErrorInfo("Error executing request", 500), ex); }
            }

            throw new AblyException(new ErrorInfo("Error exectuting request", 500));
        }
Exemplo n.º 2
0
        public async Task <AblyResponse> Execute(AblyRequest request)
        {
            var fallbackHosts = Options.FallbackHosts.ToList();

            if (CustomHost.IsNotEmpty())
            {
                // The custom host is a fallback host currently in use by the Realtime client.
                // We need to remove it from the fallback hosts
                fallbackHosts.Remove(CustomHost);
            }

            var random = new Random();

            int currentTry      = 0;
            var startTime       = Now();
            var numberOfRetries = Options.HttpMaxRetryCount;
            var host            = CustomHost.IsNotEmpty() ? CustomHost : Options.Host;

            while (currentTry < numberOfRetries)
            {
                DateTimeOffset requestTime = Now();
                if ((requestTime - startTime).TotalSeconds >= Options.HttpMaxRetryDuration.TotalSeconds)
                {
                    Logger.Error("Cumulative retry timeout of {0}s was exceeded", Config.CommulativeFailedRequestTimeOutInSeconds);
                    throw new AblyException(
                              new ErrorInfo($"Commulative retry timeout of {Config.CommulativeFailedRequestTimeOutInSeconds}s was exceeded.", 50000, null));
                }

                Logger.Debug("Executing request: " + request.Url + (currentTry > 0 ? $"try {currentTry}" : string.Empty));
                try
                {
                    var message = GetRequestMessage(request, host);
                    await LogMessage(message);

                    var response = await SendAsync(message).ConfigureAwait(false);

                    var ablyResponse = await GetAblyResponse(response);

                    LogResponse(ablyResponse, request.Url);

                    if (response.IsSuccessStatusCode)
                    {
                        return(ablyResponse);
                    }

                    if (IsRetryableResponse(response) && (Options.IsDefaultHost || Options.FallbackHostsUseDefault))
                    {
                        Logger.Warning("Failed response. Retrying. Returned response with status code: " +
                                       response.StatusCode);

                        if (TryGetNextRandomHost(fallbackHosts, random, out host))
                        {
                            Logger.Debug("Retrying using host {0}", host);
                            currentTry++;
                            continue;
                        }
                    }

                    if (request.NoExceptionOnHttpError)
                    {
                        return(ablyResponse);
                    }

                    try
                    {
                        response.EnsureSuccessStatusCode();
                    }
                    catch (HttpRequestException ex)
                    {
                        throw new AblyException(ErrorInfo.Parse(ablyResponse), ex);
                    }

                    throw AblyException.FromResponse(ablyResponse);
                }
                catch (HttpRequestException ex) when(IsRetryableError(ex) && (Options.IsDefaultHost || Options.FallbackHostsUseDefault))
                {
                    Logger.Warning("Error making a connection to Ably servers. Retrying", ex);
                    if (TryGetNextRandomHost(fallbackHosts, random, out host))
                    {
                        Logger.Debug("Retrying using host {0}", host);
                        currentTry++;
                        continue;
                    }

                    throw;
                }
                catch (TaskCanceledException ex) when(IsRetryableError(ex) && (Options.IsDefaultHost || Options.FallbackHostsUseDefault))
                {
                    Logger.Warning("Error making a connection to Ably servers. Retrying", ex);
                    if (TryGetNextRandomHost(fallbackHosts, random, out host))
                    {
                        Logger.Debug("Retrying using host {0}", host);
                        currentTry++;
                        continue;
                    }

                    throw;
                }
                catch (HttpRequestException ex)
                {
                    StringBuilder reason  = new StringBuilder(ex.Message);
                    var           innerEx = ex.InnerException;
                    while (innerEx != null)
                    {
                        reason.Append(" " + innerEx.Message);
                        innerEx = innerEx.InnerException;
                    }

                    throw new AblyException(new ErrorInfo(reason.ToString(), 50000), ex);
                }
                catch (TaskCanceledException ex)
                {
                    // if the cancellation was not requested then this is timeout.
                    if (ex.CancellationToken.IsCancellationRequested == false)
                    {
                        throw new AblyException(new ErrorInfo("Error executing request. Request timed out.", 50000), ex);
                    }
                    else
                    {
                        throw new AblyException(new ErrorInfo("Error executing request", 50000), ex);
                    }
                }
            }

            throw new AblyException(new ErrorInfo("Error exectuting request", 50000));
        }