Example #1
0
        public override async Task <string> ProceedRequestAsync(string query, TimeSpan timeout)
        {
            var mappingTaskToUriGuidTuple = new ConcurrentDictionary <Task <string>, (string, Guid)>(
                ClusterManager.EnumerateWhiteReplica().Select(uri =>
            {
                var guid = Guid.NewGuid();
                var task = Task.Run(async() =>
                {
                    var requestTask = WebRequestTask(uri, query, guid);
                    await Task.WhenAny(requestTask, Task.Delay(timeout));

                    if (requestTask.IsCompleted && !requestTask.IsFaulted)
                    {
                        return(requestTask.Result);
                    }

                    ClusterManager.MarkGrey(uri, query, TimeSpan.FromMilliseconds(500));
                    throw new TimeoutException();
                });

                return(new KeyValuePair <Task <string>, (string, Guid)>(task, (uri, guid)));
            }));

            var parallelTasks = new HashSet <Task <string> >(mappingTaskToUriGuidTuple.Keys);

            while (parallelTasks.Any())
            {
                var completedTask = await Task.WhenAny(parallelTasks);

                if (completedTask.IsFaulted)
                {
                    parallelTasks.Remove(completedTask);
                    Log.Info($"Task [{query}] faulted with [{completedTask.Exception?.GetBaseException().Message}].");
                }
                else
                {
                    foreach (var task in parallelTasks.Where(t => !t.IsCompleted))
                    {
                        var(uri, guid) = mappingTaskToUriGuidTuple[task];
                        ProceedCancelRequest(uri, guid);
                    }

                    return(completedTask.Result);
                }
            }

            throw new TimeoutException();
        }
        public override async Task <string> ProceedRequestAsync(string query, TimeSpan timeout)
        {
            var whiteReplica = ClusterManager.EnumerateWhiteReplica().ToArray();
            var uri          = whiteReplica[randomGenerator.Next(whiteReplica.Length)];
            var guid         = Guid.NewGuid();

            var requestTask = WebRequestTask(uri, query, guid);
            await Task.WhenAny(requestTask, Task.Delay(timeout));

            if (requestTask.IsCompleted && !requestTask.IsFaulted)
            {
                return(requestTask.Result);
            }

            ClusterManager.MarkGrey(uri, query, TimeSpan.FromMilliseconds(500));
            throw new TimeoutException();
        }