public static async Task <Stream> CreateAsync( Func <long, Stream> responseFactory, Func <long, ValueTask <Stream> > asyncResponseFactory, ResponseClassifier responseClassifier, int maxRetries) { return(Create(await asyncResponseFactory(0).ConfigureAwait(false), responseFactory, asyncResponseFactory, responseClassifier, maxRetries)); }
public static Stream Create( Func <long, Stream> responseFactory, Func <long, ValueTask <Stream> > asyncResponseFactory, ResponseClassifier responseClassifier, int maxRetries) { return(Create(responseFactory(0), responseFactory, asyncResponseFactory, responseClassifier, maxRetries)); }
public RetriableStreamImpl(Stream initialStream, Func <long, Stream> streamFactory, Func <long, ValueTask <Stream> > asyncStreamFactory, ResponseClassifier responseClassifier, int maxRetries) { _initialStream = EnsureStream(initialStream); _currentStream = EnsureStream(initialStream); _streamFactory = streamFactory; _responseClassifier = responseClassifier; _asyncStreamFactory = asyncStreamFactory; _maxRetries = maxRetries; }
public static Stream Create( Stream initialResponse, Func <long, Stream> streamFactory, Func <long, ValueTask <Stream> > asyncResponseFactory, ResponseClassifier responseClassifier, int maxRetries) { return(new RetriableStreamImpl(initialResponse, streamFactory, asyncResponseFactory, responseClassifier, maxRetries)); }
public void DetectsTextContentTypes(string contentType, bool isText, string expectedEncoding) { var response = new MockResponse(200); response.AddHeader(new HttpHeader("Content-Type", contentType)); Assert.AreEqual(isText, ResponseClassifier.IsTextResponse(response, out var encoding)); Assert.AreEqual(encoding?.EncodingName, expectedEncoding); }
private Task <Stream> CreateAsync( Func <long, Response> responseFactory, Func <long, Task <Response> > asyncResponseFactory, ResponseClassifier responseClassifier, int maxRetries) { return(IsAsync ? RetriableStream.CreateAsync(responseFactory, asyncResponseFactory, responseClassifier, maxRetries) : Task.FromResult(RetriableStream.Create(responseFactory, asyncResponseFactory, responseClassifier, maxRetries))); }
public void TreatsAll4xAnd5xAsErrors() { var classifier = new ResponseClassifier(); var httpMessage = new HttpMessage(new MockRequest(), new ResponseClassifier()); for (int i = 400; i < 600; i++) { httpMessage.Response = new MockResponse(i); Assert.True(classifier.IsErrorResponse(httpMessage)); } }
public static IList <IRequestModule> BuildChain(IClusterClientConfiguration config, IReplicaStorageProvider storageProvider) { var responseClassifier = new ResponseClassifier(); var requestConverter = new RequestConverter(config.Log); var requestSender = new RequestSender(config, storageProvider, responseClassifier, requestConverter, config.Transport); var resultStatusSelector = new ClusterResultStatusSelector(); var modules = new List <IRequestModule>(15 + config.Modules?.Count ?? 0) { new ErrorCatchingModule(), new RequestTransformationModule(config.RequestTransforms), new OperationNameFallbackModule(), new RequestPriorityApplicationModule() }; if (config.Modules != null) { modules.AddRange(config.Modules); } if (config.EnableTracing) { modules.Add(new TracingModule(config.ServiceName)); } modules.Add(new LoggingModule(config.LogRequestDetails, config.LogResultDetails)); modules.Add(new ResponseTransformationModule(config.ResponseTransforms)); modules.Add(new ErrorCatchingModule()); modules.Add(new RequestValidationModule()); modules.Add(new TimeoutValidationModule()); modules.Add(new RequestRetryModule(config.RetryPolicy, config.RetryStrategy)); if (config.AdaptiveThrottling != null) { modules.Add(new AdaptiveThrottlingModule(config.AdaptiveThrottling)); } if (config.ReplicaBudgeting != null) { modules.Add(new ReplicaBudgetingModule(config.ReplicaBudgeting)); } modules.Add(new AbsoluteUrlSenderModule(config.Transport, responseClassifier, config.ResponseCriteria, resultStatusSelector)); modules.Add(new RequestExecutionModule(config.ClusterProvider, config.ReplicaOrdering, config.ResponseSelector, storageProvider, requestSender, resultStatusSelector)); return(modules); }
public static IList <IRequestModule> BuildChain(IClusterClientConfiguration config, IReplicaStorageProvider storageProvider) { var responseClassifier = new ResponseClassifier(); var requestConverter = new RequestConverter(config.Log, config.DeduplicateRequestUrl); var requestSender = new RequestSender(config, storageProvider, responseClassifier, requestConverter); var resultStatusSelector = new ClusterResultStatusSelector(); // ReSharper disable once UseObjectOrCollectionInitializer var modules = new List <IRequestModule>(12 + config.Modules?.Sum(x => x.Value.Count) ?? 0); var addedModules = new HashSet <Type>(); AddModule(new LeakPreventionModule()); AddModule(new GlobalErrorCatchingModule()); AddModule(new RequestTransformationModule(config.RequestTransforms)); AddModule(new AuxiliaryHeadersModule()); // -->> user-defined modules by default inserted here <<-- // AddModule(new LoggingModule(config.Logging.LogRequestDetails, config.Logging.LogResultDetails, config.TargetServiceName)); AddModule(new ResponseTransformationModule(config.ResponseTransforms)); AddModule(new ErrorCatchingModule()); AddModule(new RequestValidationModule()); AddModule(new TimeoutValidationModule()); AddModule(new RequestRetryModule(config.RetryPolicy, config.RetryStrategyEx)); // -->> adaptive throttling module <<-- // AddModule(new AbsoluteUrlSenderModule(responseClassifier, config.ResponseCriteria, resultStatusSelector)); // -->> replica budgeting module <<-- // // -->> service-mesh module is injected before RequestExecutionModule <<-- // AddModule( new RequestExecutionModule( config.ResponseSelector, storageProvider, requestSender, resultStatusSelector)); return(modules); void AddModules(IEnumerable <IRequestModule> modulesRange) { if (modulesRange == null) { return; } foreach (var module in modulesRange) { AddModule(module); } } void AddModule(IRequestModule module) { if (config.ModulesToRemove.Contains(module.GetType())) { return; } var moduleType = module.GetType(); var isNewModule = addedModules.Add(moduleType); if (!isNewModule || config.Modules == null) { modules.Add(module); return; } var relatedModules = config.Modules.TryGetValue(moduleType, out var v) ? v : null; AddModules(relatedModules?.Before); modules.Add(module); AddModules(relatedModules?.After); } }
private static async Task ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline, bool async) { if (!s_eventSource.IsEnabled()) { if (async) { await ProcessNextAsync(pipeline, message).ConfigureAwait(false); } else { ProcessNext(pipeline, message); } return; } s_eventSource.Request(message.Request); Encoding requestTextEncoding = null; if (message.Request.TryGetHeader(HttpHeader.Names.ContentType, out var contentType) && IsTextContentType(contentType)) { requestTextEncoding = Encoding.UTF8; } if (message.Request.Content != null) { if (requestTextEncoding != null) { if (async) { await s_eventSource.RequestContentTextAsync(message.Request, requestTextEncoding, message.Cancellation); } else { s_eventSource.RequestContentText(message.Request, requestTextEncoding, message.Cancellation); } } else { if (async) { await s_eventSource.RequestContentAsync(message.Request, message.Cancellation); } else { s_eventSource.RequestContent(message.Request, message.Cancellation); } } } var before = Stopwatch.GetTimestamp(); if (async) { await ProcessNextAsync(pipeline, message).ConfigureAwait(false); } else { ProcessNext(pipeline, message); } var after = Stopwatch.GetTimestamp(); bool isError = message.ResponseClassifier.IsErrorResponse(message.Response); var textResponse = ResponseClassifier.IsTextResponse(message.Response, out Encoding responseTextEncoding); bool wrapResponseStream = s_eventSource.ShouldLogContent(isError) && message.Response.ContentStream?.CanSeek == false; if (wrapResponseStream) { message.Response.ContentStream = new LoggingStream( message.Response.ClientRequestId, s_eventSource, message.Response.ContentStream, isError, responseTextEncoding); } if (isError) { s_eventSource.ErrorResponse(message.Response); if (!wrapResponseStream && message.Response.ContentStream != null) { if (textResponse) { if (async) { await s_eventSource.ErrorResponseContentTextAsync(message.Response, responseTextEncoding, message.Cancellation).ConfigureAwait(false); } else { s_eventSource.ErrorResponseContentText(message.Response, responseTextEncoding, message.Cancellation); } } else { if (async) { await s_eventSource.ErrorResponseContentAsync(message.Response, message.Cancellation).ConfigureAwait(false); } else { s_eventSource.ErrorResponseContent(message.Response); } } } } s_eventSource.Response(message.Response); if (!wrapResponseStream && message.Response.ContentStream != null) { if (textResponse) { await s_eventSource.ResponseContentTextAsync(message.Response, responseTextEncoding, message.Cancellation).ConfigureAwait(false); } else { await s_eventSource.ResponseContentAsync(message.Response, message.Cancellation).ConfigureAwait(false); } } var elapsedMilliseconds = (after - before) * 1000 / s_frequency; if (elapsedMilliseconds > s_delayWarningThreshold) { s_eventSource.ResponseDelay(message.Response, elapsedMilliseconds); } }
public void DoesntRetryRequestFailedExceptionsWithStatusCode() { var classifier = new ResponseClassifier(); Assert.False(classifier.IsRetriableException(new RequestFailedException(500, "IO Exception"))); }
public void RetriesRequestFailedExceptionsWithoutCode() { var classifier = new ResponseClassifier(); Assert.True(classifier.IsRetriableException(new RequestFailedException(0, "IO Exception"))); }
protected async Task <Response> SendGetRequest(HttpPipelineTransport transport, HttpPipelinePolicy policy, ResponseClassifier responseClassifier = null) { using Request request = transport.CreateRequest(); request.Method = RequestMethod.Get; request.UriBuilder.Uri = new Uri("http://example.com"); return(await SendRequestAsync(transport, request, policy, responseClassifier)); }
protected static async Task <Response> SendGetRequest(HttpPipelineTransport transport, HttpPipelinePolicy policy, ResponseClassifier responseClassifier = null) { Assert.IsInstanceOf <HttpPipelineSynchronousPolicy>(policy, "Use SyncAsyncPolicyTestBase base type for non-sync policies"); using (Request request = transport.CreateRequest()) { request.Method = RequestMethod.Get; request.Uri.Reset(new Uri("http://example.com")); var pipeline = new HttpPipeline(transport, new[] { policy }, responseClassifier); return(await pipeline.SendRequestAsync(request, CancellationToken.None)); } }
protected async Task <Response> SendRequestAsync(HttpPipelineTransport transport, Action <Request> requestAction, HttpPipelinePolicy policy, ResponseClassifier responseClassifier = null, bool bufferResponse = true, CancellationToken cancellationToken = default) { await Task.Yield(); var pipeline = new HttpPipeline(transport, new[] { policy }, responseClassifier); return(await SendRequestAsync(pipeline, requestAction, bufferResponse, cancellationToken)); }
protected Task <Response> SendRequestAsync(HttpPipelineTransport transport, Action <Request> requestAction, HttpPipelinePolicy policy, ResponseClassifier responseClassifier = null, bool bufferResponse = true, CancellationToken cancellationToken = default) { return(SendRequestAsync(transport, message => requestAction(message.Request), policy, responseClassifier, bufferResponse, cancellationToken)); }
public PerCallResponseClassifier(ResponseClassifier inner, List <HttpMessageClassifier> classifiers) { _inner = inner; _classifiers = classifiers; }
public HttpMessage(Request request, ResponseClassifier responseClassifier) { Request = request ?? throw new ArgumentNullException(nameof(request)); ResponseClassifier = responseClassifier; }
protected async Task <Response> SendGetRequest(HttpPipelineTransport transport, HttpPipelinePolicy policy, ResponseClassifier responseClassifier = null, bool bufferResponse = true, Uri uri = null, CancellationToken cancellationToken = default) { return(await SendRequestAsync(transport, request => { request.Method = RequestMethod.Get; request.Uri.Reset(uri ?? new Uri("http://example.com")); }, policy, responseClassifier, bufferResponse, cancellationToken)); }
protected async Task <Response> SendGetRequest(HttpPipelineTransport transport, HttpPipelinePolicy policy, ResponseClassifier responseClassifier = null, bool bufferResponse = true) { return(await SendRequestAsync(transport, request => { request.Method = RequestMethod.Get; request.Uri.Reset(new Uri("http://example.com")); }, policy, responseClassifier, bufferResponse)); }
protected async Task <Response> SendRequestAsync(HttpPipelineTransport transport, Request request, HttpPipelinePolicy policy, ResponseClassifier responseClassifier = null) { await Task.Yield(); var pipeline = new HttpPipeline(transport, new [] { policy }, responseClassifier); return(await SendRequestAsync(pipeline, request, CancellationToken.None)); }
protected async Task <Response> SendGetRequest(HttpPipelineTransport transport, HttpPipelinePolicy policy, ResponseClassifier responseClassifier = null) { await Task.Yield(); using (Request request = transport.CreateRequest()) { request.Method = HttpPipelineMethod.Get; request.UriBuilder.Uri = new Uri("http://example.com"); var pipeline = new HttpPipeline(transport, new [] { policy }, responseClassifier); return(await SendRequestAsync(pipeline, request, CancellationToken.None)); } }
public void SetUp() { criteria = new List <IResponseCriterion>(); classifier = new ResponseClassifier(); response = Responses.Timeout; }
protected static Task <Response> SendRequest(MockTransport mockTransport, HttpPipelinePolicy policy, ResponseClassifier responseClassifier) { return(SendGetRequest(mockTransport, policy, responseClassifier)); }