Beispiel #1
0
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation.Exception is TimeoutException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return true;
            }
            else if (exceptionInformation.Exception is ProtocolViolationException)
            {
                result = new ExceptionHandlingThrowResult();
                return true;
            }
            else if (exceptionInformation.Exception is WebException)
            {
                WebException we = exceptionInformation.Exception as WebException;
                HttpWebResponse errorResponse = we.Response as HttpWebResponse;

                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    if (errorResponse.StatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.
                        result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return true;
                    }

                    if (errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        // The address is correct, but the server processing failed.
                        // Retry the operation without re-resolving the address.
                        result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, true, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return true;
                    }
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return true;
                }
            }

            result = null;
            return false;
        }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation == null)
            {
                throw new ArgumentNullException(nameof(exceptionInformation));
            }

            if (retrySettings == null)
            {
                throw new ArgumentNullException(nameof(retrySettings));
            }

            result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);

            return true;
        }
Beispiel #3
0
        public async Task <IServiceRemotingClient> GetClientAsync(ResolvedServicePartition previousRsp, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
        {
            IServiceRemotingClient inner = await _inner.GetClientAsync(
                previousRsp, targetReplicaSelector, listenerName, retrySettings, cancellationToken);

            return(new CorrelatingServiceRemotingClient(inner));
        }
Beispiel #4
0
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation.Exception is TimeoutException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }
            else if (exceptionInformation.Exception is ProtocolViolationException)
            {
                result = new ExceptionHandlingThrowResult();
                return(true);
            }
            else if (exceptionInformation.Exception is SocketException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }

            WebException we = exceptionInformation.Exception as WebException;

            if (we == null)
            {
                we = exceptionInformation.Exception.InnerException as WebException;
            }

            if (we != null)
            {
                HttpWebResponse errorResponse = we.Response as HttpWebResponse;

                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    if (errorResponse.StatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.
                        result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return(true);
                    }

                    if (errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        // The address is correct, but the server processing failed.
                        // This could be due to conflicts when writing the word to the dictionary.
                        // Retry the operation without re-resolving the address.
                        result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, true, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return(true);
                    }
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return(true);
                }
            }

            result = null;
            return(false);
        }
Beispiel #5
0
 /// <summary>
 /// Handle exception using standard fabric client
 /// </summary>
 /// <param name="client"></param>
 /// <param name="exceptionInformation"></param>
 /// <param name="retrySettings"></param>
 /// <param name="cancellationToken"></param>
 /// <returns></returns>
 public async Task <OperationRetryControl> ReportOperationExceptionAsync(IServiceRemotingClient client, ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
 {
     return(await this.innerClientFactory.ReportOperationExceptionAsync((client as ExtendedFabricTransportServiceRemotingClient).BaseClient, exceptionInformation, retrySettings, cancellationToken));
 }
        public async Task <IServiceRemotingClient> GetClientAsync(ResolvedServicePartition previousRsp, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings,
                                                                  CancellationToken cancellationToken)
        {
            var client = await _innerClientFactory.GetClientAsync(
                previousRsp,
                targetReplicaSelector,
                listenerName,
                retrySettings,
                cancellationToken);

            return(new FabricTransportServiceRemotingClient(client, previousRsp.ServiceName, _logger, _serviceMethodDispatcher));
        }
        public async Task <IServiceRemotingClient> GetClientAsync(
            ResolvedServicePartition previousRsp, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings,
            CancellationToken cancellationToken)
        {
            IServiceRemotingClient remotingClient = await this.innerRemotingClientFactory.GetClientAsync(
                previousRsp,
                targetReplicaSelector,
                listenerName,
                retrySettings,
                cancellationToken);

            return(new MyServiceRemotingClient(remotingClient));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ActorProxyFactory"/> class.
 /// </summary>
 /// <param name="retrySettings">Retry settings for the remote object calls  made by proxy.</param>
 public ActorProxyFactory(OperationRetrySettings retrySettings = null)
 {
 }
 public SubscriberServiceCloud(ICommunicationClientFactory <WcfCommunicationClient <ISubscription> > communicationClientFactory, Uri serviceUri, ServicePartitionKey partitionKey = null, TargetReplicaSelector targetReplicaSelector = TargetReplicaSelector.Default, string listenerName = null, OperationRetrySettings retrySettings = null)
     : base(communicationClientFactory, serviceUri, partitionKey, targetReplicaSelector, listenerName, retrySettings)
 {
 }
 public void Initialise()
 {
     this.httpExceptionHandler   = new HttpExceptionHandler();
     this.operationRetrySettings = new OperationRetrySettings();
 }
Beispiel #11
0
 public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
 {
     result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount);
     //// Log Error Here.
     return(true);
 }
Beispiel #12
0
        bool IExceptionHandler.TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            Exception exception = exceptionInformation.Exception;

            if (exception is ActorConcurrencyLockTimeoutException)
            {
                if (ActorLogicalCallContext.IsPresent())
                {
                    result = new ExceptionHandlingThrowResult
                    {
                        ExceptionToThrow = exception
                    };
                    return(true);
                }
                result = new ExceptionHandlingRetryResult(exception, true, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }
            result = null;
            return(false);
        }
Beispiel #13
0
 public WCFSCADATransactionClient(ICommunicationClientFactory <WcfCommunicationClient <ITransactionSCADA> > communicationClientFactory, Uri serviceUri, ServicePartitionKey partitionKey = null, TargetReplicaSelector targetReplicaSelector = TargetReplicaSelector.Default, string listenerName = null, OperationRetrySettings retrySettings = null)
     : base(communicationClientFactory, serviceUri, partitionKey, targetReplicaSelector, listenerName, retrySettings)
 {
 }
        /// <summary>
        /// Handles the exceptions that occur in the CommunicationClient when sending a message to the Service.
        /// </summary>
        /// <param name="client">Communication client.</param>
        /// <param name="exceptionInformation">Information about exception that happened while communicating with the service.</param>
        /// <param name="retrySettings">Specifies the retry policy that should be used for handling the reported exception.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>A System.Threading.Tasks.Task that represents outstanding operation. The result
        /// of the Task is a Microsoft.ServiceFabric.Services.Communication.Client.OperationRetryControl
        /// object that provides information on retry policy for this exception.</returns>
        public Task <OperationRetryControl> ReportOperationExceptionAsync(IServiceRemotingClient client, ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
        {
            IServiceRemotingClient effectiveClient = (client as IWrappingClient)?.InnerClient ?? client;

            return(this.innerClientFactory.ReportOperationExceptionAsync(effectiveClient, exceptionInformation, retrySettings, cancellationToken));
        }
        /// <summary>
        /// Resolves a partition of the specified service containing one or more communication
        /// listeners and returns a client to communicate to the endpoint corresponding to
        /// the given listenerName. The endpoint of the service is of the form - {"Endpoints":{"Listener1":"Endpoint1","Listener2":"Endpoint2"
        /// ...}}
        /// </summary>
        /// <param name="previousRsp">Previous ResolvedServicePartition value.</param>
        /// <param name="targetReplicaSelector">Specifies which replica in the partition identified by the partition key, the client should connect to.</param>
        /// <param name="listenerName">Specifies which listener in the endpoint of the chosen replica, to which the client should connect to.</param>
        /// <param name="retrySettings">Specifies the retry policy that should be used for exceptions that occur when creating the client.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>A System.Threading.Tasks.Task that represents outstanding operation. The result of the Task is the <see cref="CorrelatingServiceRemotingClient"/> object.</returns>
        public async Task <IServiceRemotingClient> GetClientAsync(ResolvedServicePartition previousRsp, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
        {
            var innerClient = await this.innerClientFactory.GetClientAsync(previousRsp, targetReplicaSelector, listenerName, retrySettings, cancellationToken).ConfigureAwait(false);

            return(new CorrelatingServiceRemotingClient(innerClient, previousRsp.ServiceName, methodNameProvider));
        }
 public ServiceFabricDMSClient(ICommunicationClientFactory <WcfCommunicationClient <IDMSContract> > communicationClientFactory, Uri serviceUri, ServicePartitionKey partitionKey = null, TargetReplicaSelector targetReplicaSelector = TargetReplicaSelector.Default, string listenerName = null, OperationRetrySettings retrySettings = null)
     : base(communicationClientFactory, serviceUri, partitionKey, targetReplicaSelector, listenerName, retrySettings)
 {
 }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            Exception e = exceptionInformation.Exception;

            Logger.Debug("OnHandleException {0}", e);

            if (e is TimeoutException)
            {
                result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return true;
            }

            if (e is ProtocolViolationException)
            {
                result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return true;
            }

            if (e is HttpRequestException)
            {
                HttpRequestException he = (HttpRequestException) e;

                // this should not happen, but let's do a sanity check
                if (null == he.InnerException)
                {
                    result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return true;
                }

                e = he.InnerException;
            }

            if (e is WebException)
            {
                WebException we = (WebException) e;
                HttpWebResponse errorResponse = we.Response as HttpWebResponse;

                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    if (errorResponse.StatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.
                        result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return true;
                    }

                    if (errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        // The address is correct, but the server processing failed.
                        // This could be due to conflicts when writing the word to the dictionary.
                        // Retry the operation without re-resolving the address.
                        result = new ExceptionHandlingRetryResult(e, true, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return true;
                    }
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return true;
                }
            }

            result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
            return true;
        }
Beispiel #18
0
        public async Task <IServiceRemotingClient> GetClientAsync(ResolvedServicePartition previousRsp, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
        {
            var client = await _inner.GetClientAsync(previousRsp, targetReplicaSelector, listenerName, retrySettings, cancellationToken).ConfigureAwait(false);

            return(new ServiceRemotingClientWrapper(client));
        }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            Exception e = exceptionInformation.Exception;

            Logger.Debug("OnHandleException {0}", e);

            if (e is TimeoutException)
            {
                result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }

            if (e is ProtocolViolationException)
            {
                result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                return(true);
            }

            if (e is HttpRequestException)
            {
                HttpRequestException he = (HttpRequestException)e;

                // this should not happen, but let's do a sanity check
                if (null == he.InnerException)
                {
                    result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return(true);
                }

                e = he.InnerException;
            }

            if (e is WebException)
            {
                WebException    we            = (WebException)e;
                HttpWebResponse errorResponse = we.Response as HttpWebResponse;

                if (we.Status == WebExceptionStatus.ProtocolError)
                {
                    if (errorResponse.StatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.
                        result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return(true);
                    }

                    if (errorResponse.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        // The address is correct, but the server processing failed.
                        // This could be due to conflicts when writing the word to the dictionary.
                        // Retry the operation without re-resolving the address.
                        result = new ExceptionHandlingRetryResult(e, true, retrySettings, retrySettings.DefaultMaxRetryCount);
                        return(true);
                    }
                }

                if (we.Status == WebExceptionStatus.Timeout ||
                    we.Status == WebExceptionStatus.RequestCanceled ||
                    we.Status == WebExceptionStatus.ConnectionClosed ||
                    we.Status == WebExceptionStatus.ConnectFailure)
                {
                    result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
                    return(true);
                }
            }

            result = new ExceptionHandlingRetryResult(e, false, retrySettings, retrySettings.DefaultMaxRetryCount);
            return(true);
        }
Beispiel #20
0
        public async Task <OperationRetryControl> ReportOperationExceptionAsync(IServiceRemotingClient client, ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
        {
            var exceptionTelemetry = new ExceptionTelemetry();

            exceptionTelemetry.Context.Operation.Id = CallContext.GetData(Constants.CorrelationId)?.ToString();
            exceptionTelemetry.Exception            = exceptionInformation.Exception;
            exceptionTelemetry.Message = "An unhandled exception occured";

            _telemetryClient.TrackException(exceptionTelemetry);

            //Use the inner client since this is the one who does all the requests etc
            var wrapperClient = client as ServiceRemotingClientWrapper;
            var innerClient   = await _inner.GetClientAsync(wrapperClient.ResolvedServicePartition, TargetReplicaSelector.Default, wrapperClient.ListenerName, retrySettings, cancellationToken);

            return(await _inner.ReportOperationExceptionAsync(innerClient, exceptionInformation, retrySettings, cancellationToken));
        }
        public CorrelatingServiceProxyFactory(Func <IServiceRemotingCallbackMessageHandler, IServiceRemotingClientFactory> createServiceRemotingClientFactory = null, OperationRetrySettings retrySettings = null, Action <CallSummary> raiseSummary = null, string remoteServiceName = null)
        {
            _serviceProxyFactory = new ServiceProxyFactory(
                (callbackClient) =>
            {
                if (createServiceRemotingClientFactory == null)
                {
                    return(new CorrelatingFabricTransportServiceRemotingClientFactory <TServiceInterface>(inner: null, raiseSummary: raiseSummary, remoteServiceName: remoteServiceName));
                }

                IServiceRemotingClientFactory innerClientFactory = createServiceRemotingClientFactory(callbackClient);

                if (innerClientFactory is CorrelatingFabricTransportServiceRemotingClientFactory <TServiceInterface> )
                {
                    return(innerClientFactory);
                }

                return(new CorrelatingFabricTransportServiceRemotingClientFactory <TServiceInterface>(inner: innerClientFactory, raiseSummary: raiseSummary, remoteServiceName: remoteServiceName));
            },
                retrySettings);
        }
        async Task <IServiceRemotingClient> ICommunicationClientFactory <IServiceRemotingClient> .GetClientAsync(Uri serviceUri, ServicePartitionKey partitionKey, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
        {
            var client = await _innerClientFactory.GetClientAsync(
                serviceUri,
                partitionKey,
                targetReplicaSelector,
                listenerName,
                retrySettings,
                cancellationToken);

            return(new CustomFabricTransportServiceRemotingClient(client));
        }
 public Task <OperationRetryControl> ReportOperationExceptionAsync(
     IServiceRemotingClient client, ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
 {
     return(this.innerRemotingClientFactory.ReportOperationExceptionAsync(
                ((MyServiceRemotingClient)client).InnerClient,
                exceptionInformation,
                retrySettings,
                cancellationToken));
 }
 Task <OperationRetryControl> ICommunicationClientFactory <IServiceRemotingClient> .ReportOperationExceptionAsync(IServiceRemotingClient client, ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
 {
     if (client is CustomFabricTransportServiceRemotingClient)
     {
         return(_innerClientFactory.ReportOperationExceptionAsync(
                    (client as CustomFabricTransportServiceRemotingClient).InnerClient,
                    exceptionInformation,
                    retrySettings,
                    cancellationToken));
     }
     else
     {
         return(_innerClientFactory.ReportOperationExceptionAsync(
                    client,
                    exceptionInformation,
                    retrySettings,
                    cancellationToken));
     }
 }
        public Task <OperationRetryControl> ReportOperationExceptionAsync(IServiceRemotingClient client, ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings,
                                                                          CancellationToken cancellationToken)
        {
            var fabricTransportServiceRemotingClient = client as FabricTransportServiceRemotingClient;

            _logger.ServiceClientFailed(
                fabricTransportServiceRemotingClient?.ResolvedServicePartition.ServiceName,
                ServiceRequestContext.Current?.GetCustomHeader(),
                exceptionInformation.Exception);
            return(_innerClientFactory.ReportOperationExceptionAsync(
                       fabricTransportServiceRemotingClient?.InnerClient,
                       exceptionInformation,
                       retrySettings,
                       cancellationToken));
        }
Beispiel #26
0
        bool IExceptionHandler.TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation.Exception is TimeoutException ||
                exceptionInformation.Exception is ConnectionFailedException ||
                exceptionInformation.Exception is OperationCanceledException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, 1);
                return(true);
            }

            else if (exceptionInformation.Exception is ProcessingException)
            {
                result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, 0);
                return(true);
            }
            result = null;
            return(false);
        }
Beispiel #27
0
        /// <summary>
        /// Return <see cref="ExtendedFabricTransportServiceRemotingClient"/> client
        /// </summary>
        /// <param name="serviceUri"></param>
        /// <param name="partitionKey"></param>
        /// <param name="targetReplicaSelector"></param>
        /// <param name="listenerName"></param>
        /// <param name="retrySettings"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <IServiceRemotingClient> GetClientAsync(Uri serviceUri, ServicePartitionKey partitionKey, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
        {
            var baseClient = await this.innerClientFactory.GetClientAsync(serviceUri, partitionKey, targetReplicaSelector, listenerName, retrySettings, cancellationToken);

            return(new ExtendedFabricTransportServiceRemotingClient(baseClient));
        }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation == null)
            {
                throw new ArgumentNullException(nameof(exceptionInformation));
            }

            var ex = exceptionInformation.Exception;

            // errors where we didn't get a response from the service.

            if (ex is TaskCanceledException || ex is TimeoutException)
            {
                _logger.RetryingServiceCall(ex.GetType().Name);

                return CreateExceptionHandlingRetryResult(false, ex, out result);
            }

            if (ex is ProtocolViolationException)
            {
                _logger.RetryingServiceCall("ProtocolViolationException", null, ex);

                return CreateExceptionHandlingRetryResult(false, ex, out result);
            }

            var webEx = ex as WebException ?? ex.InnerException as WebException;
            if (webEx != null)
            {
                if (webEx.Status == WebExceptionStatus.Timeout ||
                    webEx.Status == WebExceptionStatus.RequestCanceled ||
                    webEx.Status == WebExceptionStatus.ConnectionClosed ||
                    webEx.Status == WebExceptionStatus.ConnectFailure)
                {
                    _logger.RetryingServiceCall("WebExceptionStatus " + webEx.Status, null, ex);

                    return CreateExceptionHandlingRetryResult(false, webEx, out result);
                }
            }

            // we got a response from the service - let's try to get the StatusCode to see if we should retry.

            if (_options.RetryHttpStatusCodeErrors)
            {
                HttpStatusCode? httpStatusCode = null;
                HttpWebResponse webResponse = null;
                HttpResponseMessage responseMessage = null;

                var httpEx = ex as HttpResponseException;
                if (httpEx != null)
                {
                    responseMessage = httpEx.Response;
                    httpStatusCode = httpEx.Response.StatusCode;
                }
                else if (webEx != null)
                {
                    webResponse = webEx.Response as HttpWebResponse;
                    httpStatusCode = webResponse?.StatusCode;
                }

                if (httpStatusCode.HasValue)
                {
                    if (httpStatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.

                        _logger.RetryingServiceCall("HTTP 404");

                        result = new ExceptionHandlingRetryResult(
                            exceptionId: "HTTP 404",
                            isTransient: false,
                            retryDelay: TimeSpan.FromMilliseconds(100),
                            maxRetryCount: 2);

                        return true;
                    }

                    if ((int)httpStatusCode >= 500 && (int)httpStatusCode < 600)
                    {
                        // The address is correct, but the server processing failed.
                        // Retry the operation without re-resolving the address.

                        // we want to log the response in case it contains useful information (e.g. in dev environments)
                        string errorResponse = null;
                        if (webResponse != null)
                        {
                            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
                            {
                                errorResponse = streamReader.ReadToEnd();
                            }
                        }
                        else if (responseMessage != null)
                        {
                            // not sure if just calling ReadAsStringAsync().Result can result in a deadlock.
                            // so better safe than sorry...
                            // http://stackoverflow.com/questions/22628087/calling-async-method-synchronously
                            // AsyncEx library would be good but I don't want to take a dependency on that just for this one case.
                            errorResponse = Task.Run(() => responseMessage.Content.ReadAsStringAsync()).Result;
                        }

                        _logger.RetryingServiceCall($"HTTP {(int) httpStatusCode}", errorResponse);

                        return CreateExceptionHandlingRetryResult(true, ex, out result);
                    }
                }
            }

            _logger.ServiceCallFailed(ex);

            result = null;
            return false;
        }
Beispiel #29
0
        public async Task <IServiceRemotingClient> GetClientAsync(Uri serviceUri, ServicePartitionKey partitionKey, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
        {
            IServiceRemotingClient inner = await _inner.GetClientAsync(
                serviceUri, partitionKey, targetReplicaSelector, listenerName, retrySettings, cancellationToken);

            return(new CorrelatingServiceRemotingClient(inner));
        }
 public Task <IServiceRemotingClient> GetClientAsync(Uri serviceUri, ServicePartitionKey partitionKey, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
 {
     return(_innerServiceRemotingClientFactory.GetClientAsync(serviceUri, partitionKey, targetReplicaSelector, listenerName, retrySettings, cancellationToken));
 }
Beispiel #31
0
        public async Task <OperationRetryControl> ReportOperationExceptionAsync(IServiceRemotingClient client, ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
        {
            if (client is CorrelatingServiceRemotingClient correlatingClient)
            {
                client = correlatingClient.Inner;
            }

            return(await _inner.ReportOperationExceptionAsync(client, exceptionInformation, retrySettings, cancellationToken));
        }
 public Task <IServiceRemotingClient> GetClientAsync(ResolvedServicePartition previousRsp, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
 {
     return(_innerServiceRemotingClientFactory.GetClientAsync(previousRsp, targetReplicaSelector, listenerName, retrySettings, cancellationToken));
 }
        public CorrelatingServiceProxyFactory(Func <IServiceRemotingCallbackClient, IServiceRemotingClientFactory> createServiceRemotingClientFactory = null, OperationRetrySettings retrySettings = null)
        {
            methodNameProvider = new MethodNameProvider(true /* threadSafe */);

            // Layer the factory structure so the hierarchy will look like this:
            // CorrelatingServiceProxyFactory
            //  --> ServiceProxyFactory
            //      --> CorrelatingServiceRemotingFactory
            //          --> <Factory created by createServcieRemotingClientFactory>
            serviceProxyFactory = new ServiceProxyFactory(
                callbackClient =>
            {
                IServiceRemotingClientFactory innerClientFactory = createServiceRemotingClientFactory(callbackClient);
                return(new CorrelatingServiceRemotingClientFactory(innerClientFactory, methodNameProvider));
            },
                retrySettings);
        }
        public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result)
        {
            if (exceptionInformation == null)
            {
                throw new ArgumentNullException(nameof(exceptionInformation));
            }

            var ex = exceptionInformation.Exception;

            // errors where we didn't get a response from the service.

            if (ex is TaskCanceledException || ex is TimeoutException)
            {
                _logger.RetryingServiceCall(ex.GetType().Name);

                return(CreateExceptionHandlingRetryResult(false, ex, out result));
            }

            if (ex is ProtocolViolationException)
            {
                _logger.RetryingServiceCall("ProtocolViolationException", null, ex);

                return(CreateExceptionHandlingRetryResult(false, ex, out result));
            }

            var webEx = ex as WebException ?? ex.InnerException as WebException;

            if (webEx != null)
            {
                if (webEx.Status == WebExceptionStatus.Timeout ||
                    webEx.Status == WebExceptionStatus.RequestCanceled ||
                    webEx.Status == WebExceptionStatus.ConnectionClosed ||
                    webEx.Status == WebExceptionStatus.ConnectFailure)
                {
                    _logger.RetryingServiceCall("WebExceptionStatus " + webEx.Status, null, ex);

                    return(CreateExceptionHandlingRetryResult(false, webEx, out result));
                }
            }

            // we got a response from the service - let's try to get the StatusCode to see if we should retry.

            if (_options.RetryHttpStatusCodeErrors)
            {
                HttpStatusCode?     httpStatusCode  = null;
                HttpWebResponse     webResponse     = null;
                HttpResponseMessage responseMessage = null;

                var httpEx = ex as HttpResponseException;
                if (httpEx != null)
                {
                    responseMessage = httpEx.Response;
                    httpStatusCode  = httpEx.Response.StatusCode;
                }
                else if (webEx != null)
                {
                    webResponse    = webEx.Response as HttpWebResponse;
                    httpStatusCode = webResponse?.StatusCode;
                }

                if (httpStatusCode.HasValue)
                {
                    if (httpStatusCode == HttpStatusCode.NotFound)
                    {
                        // This could either mean we requested an endpoint that does not exist in the service API (a user error)
                        // or the address that was resolved by fabric client is stale (transient runtime error) in which we should re-resolve.

                        _logger.RetryingServiceCall("HTTP 404");

                        result = new ExceptionHandlingRetryResult(
                            exceptionId: "HTTP 404",
                            isTransient: false,
                            retryDelay: TimeSpan.FromMilliseconds(100),
                            maxRetryCount: 2);

                        return(true);
                    }

                    if ((int)httpStatusCode >= 500 && (int)httpStatusCode < 600)
                    {
                        // The address is correct, but the server processing failed.
                        // Retry the operation without re-resolving the address.

                        // we want to log the response in case it contains useful information (e.g. in dev environments)
                        string errorResponse = null;
                        if (webResponse != null)
                        {
                            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
                            {
                                errorResponse = streamReader.ReadToEnd();
                            }
                        }
                        else if (responseMessage != null)
                        {
                            // not sure if just calling ReadAsStringAsync().Result can result in a deadlock.
                            // so better safe than sorry...
                            // http://stackoverflow.com/questions/22628087/calling-async-method-synchronously
                            // AsyncEx library would be good but I don't want to take a dependency on that just for this one case.
                            errorResponse = Task.Run(() => responseMessage.Content.ReadAsStringAsync()).Result;
                        }

                        _logger.RetryingServiceCall($"HTTP {(int) httpStatusCode}", errorResponse);

                        return(CreateExceptionHandlingRetryResult(true, ex, out result));
                    }
                }
            }

            _logger.ServiceCallFailed(ex);

            result = null;
            return(false);
        }