public override async Task <string> ProcessRequestAsync(string query, TimeSpan timeout) { timeout = TimeSpan.FromSeconds(timeout.TotalSeconds / ReplicaAddresses.Length); var orderedAddresses = ReplicaAddresses.OrderBy(addr => requestStatistics[addr].GetValue()).ToArray(); foreach (var uri in orderedAddresses) { var request = CreateRequest(uri + "?query=" + query); Log.InfoFormat("Processing {0}", request.RequestUri); timer.Start(); var task = ProcessRequestAsync(request); await Task.WhenAny(task, Task.Delay(timeout)); timer.Stop(); requestStatistics[uri].Update(timer.ElapsedMilliseconds); timer.Reset(); if (task.IsCompleted && !task.IsFaulted) { return(task.Result); } } throw new TimeoutException(); }
public override async Task <string> ProcessRequestAsync(string query, TimeSpan timeout) { foreach (var uri in ReplicaAddresses.OrderBy(x => random.Next())) { var webRequest = CreateRequest(uri + "?query=" + query); var resultTask = ProcessRequestAsync(webRequest); Console.WriteLine($"Processing {webRequest.RequestUri}"); Tasks.Add(resultTask); if (TryCheckIfPreviousCompleted(out var completed)) { Console.WriteLine($"While processing {webRequest.RequestUri} old task {completed.Id} was completed"); return(completed.Result); } await Task.WhenAny(resultTask, Task.Delay(GetSoftTimeout(timeout))); if (resultTask.IsCompleted) { return(resultTask.Result); } } // wait extra Console.WriteLine($"Waiting extra than timeout {timeout.ToString()}"); var answered = await Task.WhenAny(Tasks); if (answered.IsCompleted) { return(answered.Result); } // or do not wait excess throw new TimeoutException(); }
public async override Task <string> ProcessRequestAsync(string query, TimeSpan timeout) { var timer = Stopwatch.StartNew(); Tuple <long, int> valueForLinq; var webRequests = ReplicaAddresses .OrderBy(uri => { replicaAverageDelay.TryGetValue(uri, out valueForLinq); return(valueForLinq.Item1); }) .ToDictionary(uri => uri, uri => CreateRequest(uri + "?query=" + query)); timeout = new TimeSpan((long)(timeout.Ticks * 1.0 / ReplicaAddresses.Length)); var tasksToAwait = new ConcurrentBag <Task <string> >(); foreach (var pair in webRequests) { var tempPair = pair; Log.InfoFormat("Processing {0}", tempPair.Value.RequestUri); tasksToAwait.Add(ProcessRequestAsync(tempPair.Value)); var resultTask = await Task.WhenAny(tasksToAwait); Task.WaitAny(resultTask, Task.Delay(timeout)); if (!resultTask.IsCompleted) { continue; } if (!resultTask.IsFaulted) { var processTime = timer.ElapsedMilliseconds; Tuple <long, int> currentValue; replicaAverageDelay.TryGetValue(tempPair.Key, out currentValue); var newAverDelay = (currentValue.Item1 * currentValue.Item2 + processTime) / (currentValue.Item2 + 1); replicaAverageDelay.TryUpdate(tempPair.Key, Tuple.Create(newAverDelay, currentValue.Item2 + 1), currentValue); return(resultTask.Result); } } throw new TimeoutException(); }
public override async Task <string> ProcessRequestAsync(string query, TimeSpan timeout) { foreach (var uri in ReplicaAddresses.OrderBy(x => random.Next())) { var webRequest = CreateRequest(uri + "?query=" + query); var resultTask = ProcessRequestAsync(webRequest); Console.WriteLine($"Processing {webRequest.RequestUri}"); await Task.WhenAny(resultTask, Task.Delay(GetSoftTimeout(timeout))); if (resultTask.IsCompleted) { return(resultTask.Result); } } throw new TimeoutException(); }
public override async Task <string> ProcessRequestAsync(string query, TimeSpan timeout) { timeout = TimeSpan.FromSeconds(timeout.TotalSeconds / ReplicaAddresses.Length); var orderedAddresses = ReplicaAddresses.OrderBy(addr => requestStatistics[addr].GetValue()).ToArray(); orderedAddresses.ForEach(uri => stopwatches[uri] = new Stopwatch()); var tasksPool = new Dictionary <string, Task <string> >(); foreach (var uri in orderedAddresses) { var request = CreateRequest(uri + "?query=" + query); Log.InfoFormat("Processing {0}", request.RequestUri); tasksPool[uri] = ProcessRequestAsync(request); var task = Task.WhenAny(tasksPool.Values); await Task.WhenAny(task, Task.Delay(timeout)); if (task.IsCompleted && !task.IsFaulted) { stopwatches.Values.ForEach(timer => timer.Stop()); var completed = tasksPool.First(pair => pair.Value.IsCompleted).Key; requestStatistics[completed].Update(stopwatches[completed].ElapsedMilliseconds); stopwatches.Values.ForEach(timer => timer.Reset()); return(task.Result.Result); } stopwatches[uri].Stop(); requestStatistics[uri].Update(stopwatches[uri].ElapsedMilliseconds); stopwatches[uri].Start(); } throw new TimeoutException(); }