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();
        }
Exemplo n.º 3
0
        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();
        }