public static IEnumerable <TResponse> SendAll <TRequest, TResponse>( this IServiceClient client, int batchSize, IEnumerable <TRequest> requests, CancellationToken?cancellationToken = null, IProgressReporter progressReporter = null) where TRequest : IReturn <TResponse> { var responses = new List <TResponse>(); progressReporter?.Started(); var requestBatches = BatchesOf(requests, batchSize) .ToList(); var totalCount = requestBatches.Sum(b => b.Length); foreach (var requestBatch in requestBatches) { var firstRequest = requestBatch.First(); var requestNameResolver = EndpointRequestNameResolvers .GetOrAdd(client, serviceClient => new ServerRequestNameResolver()); var serverRequestName = requestNameResolver.ResolveRequestName(client, firstRequest); responses.AddRange(SendBatch <TResponse>(client, serverRequestName, requestBatch.Cast <object>())); progressReporter?.Progress(responses.Count, totalCount); if (cancellationToken.HasValue && cancellationToken.Value.IsCancellationRequested) { break; } } progressReporter?.Completed(); return(responses); }
private IEnumerable <TDomainObject> GetPaginatedResults <TDomainObject, TRequest, TResponse>(TRequest requestDto, TResponse responseDto, CancellationToken?cancellationToken, IProgressReporter progressReporter) where TRequest : IPaginatedRequest, IReturn <TResponse> where TResponse : IPaginatedResponse <TDomainObject> { var totalCount = responseDto.TotalCount; for (var count = 0; count < totalCount;) { if (responseDto.DomainObjects == null) { break; } if (cancellationToken.HasValue && cancellationToken.Value.IsCancellationRequested) { break; } foreach (var domainObject in responseDto.DomainObjects) { yield return(domainObject); } count += responseDto.DomainObjects.Count; progressReporter?.Progress(count, totalCount); if (count >= totalCount || count >= responseDto.TotalCount || !responseDto.DomainObjects.Any() || string.IsNullOrEmpty(responseDto.Cursor)) { break; } requestDto.Cursor = responseDto.Cursor; responseDto = Get(requestDto); } progressReporter?.Completed(); }
public static IEnumerable <TResponse> SendAll <TRequest, TResponse>( this IServiceClient client, int batchSize, IEnumerable <TRequest> requests, Action <TRequest, ResponseStatus> failedRequestHandler = null, CancellationToken?cancellationToken = null, IProgressReporter progressReporter = null) where TRequest : IReturn <TResponse> { var responses = new List <TResponse>(); progressReporter?.Started(); var requestBatches = BatchesOf(requests, batchSize) .ToList(); var totalCount = requestBatches.Sum(b => b.Length); var failedRequests = 0; foreach (var requestBatch in requestBatches) { var firstRequest = requestBatch.First(); var requestNameResolver = EndpointRequestNameResolvers .GetOrAdd(client, serviceClient => new ServerRequestNameResolver()); var serverRequestName = requestNameResolver.ResolveRequestName(client, firstRequest); var batchRequests = requestBatch.ToList(); while (true) { if (cancellationToken.HasValue && cancellationToken.Value.IsCancellationRequested) { break; } try { var batchResponses = SendBatch <TResponse>(client, serverRequestName, batchRequests.Cast <object>()); responses.AddRange(batchResponses); break; } catch (WebServiceException webServiceException) { if (failedRequestHandler != null && (webServiceException.ResponseStatus?.Meta?.TryGetValue("AutoBatchIndex", out var textValue) ?? false) && int.TryParse(textValue, out var batchIndex) && batchIndex >= 0 && batchIndex < requestBatch.Length) { failedRequestHandler(batchRequests[batchIndex], webServiceException.ResponseStatus); ++failedRequests; batchRequests.RemoveAt(batchIndex); if (!batchRequests.Any()) { break; } if (failedRequests > totalCount / 4) { throw new WebServiceException($"Too many failed batch requests ({failedRequests} out of {totalCount}) for {serverRequestName}.", webServiceException) { StatusCode = 500 } } ; continue; } throw; } } progressReporter?.Progress(responses.Count, totalCount); if (cancellationToken.HasValue && cancellationToken.Value.IsCancellationRequested) { break; } } progressReporter?.Completed(); return(responses); }