using Volo.Abp.Json; namespace KonSoft.InternalGateway.Aggregations.Base; public abstract class AggregateRemoteServiceBase : IAggregateRemoteService { private readonly IHttpContextAccessor _httpContextAccessor; private readonly ILogger> _logger; protected IJsonSerializer JsonSerializer { get; } protected AggregateRemoteServiceBase(IHttpContextAccessor httpContextAccessor, IJsonSerializer jsonSerializer, ILogger> logger) { _httpContextAccessor = httpContextAccessor; JsonSerializer = jsonSerializer; _logger = logger; } public async Task> GetMultipleAsync( Dictionary serviceNameWithUrlDictionary) { Dictionary> completedTasks = new Dictionary>(); Dictionary> runningTasks = new Dictionary>(); Dictionary completedResult = new Dictionary(); using (HttpClient httpClient = CreateHttpClient()) { foreach (var service in serviceNameWithUrlDictionary) { Task requestTask = MakeRequestAsync(httpClient, service.Value); runningTasks.Add(service.Key, requestTask); } while (runningTasks.Count > 0) { KeyValuePair> completedTask = await WaitForAnyTaskAsync(runningTasks); runningTasks.Remove(completedTask.Key); try { TDto result = await completedTask.Value; completedTasks.Add(completedTask.Key, completedTask.Value); completedResult.Add(completedTask.Key, result); _logger.LogInformation("Localization Key: {0}, Value: {1}", completedTask.Key, result); } catch (Exception ex) { _logger.LogInformation("Error for the {0}: {1}", completedTask.Key, ex.Message); } } } return completedResult; } private HttpClient CreateHttpClient() { var httpClient = new HttpClient(); var headers = _httpContextAccessor.HttpContext?.Request.Headers; if (headers != null) { foreach (var header in headers) { httpClient.DefaultRequestHeaders.Add(header.Key, header.Value.ToArray()); } } return httpClient; } public async Task MakeRequestAsync(HttpClient httpClient, string url) { try { HttpResponseMessage response = await httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); return JsonSerializer.Deserialize(content); } catch (Exception e) { _logger.LogInformation("Error making request to {0}: {1}", url, e.Message); throw; } } public async Task>> WaitForAnyTaskAsync( Dictionary> tasks) { var completedTask = Task.WhenAny(tasks.Values); var result = await completedTask; var completedTaskPair = tasks.First(kv => kv.Value == result); return completedTaskPair; } }