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; }
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)); }
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); }
/// <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(); }
public bool TryHandleException(ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, out ExceptionHandlingResult result) { result = new ExceptionHandlingRetryResult(exceptionInformation.Exception, false, retrySettings, retrySettings.DefaultMaxRetryCount); //// Log Error Here. return(true); }
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); }
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; }
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); }
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)); }
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); }
/// <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; }
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)); }
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); }