Example #1
0
        private async Task <QosResult> GetSortedRegionLatencies(int timeoutMs,
                                                                Dictionary <string, string> dataCenterMap, int pingsPerRegion, int degreeOfParallelism)
        {
            RegionPinger[] regionPingers = new RegionPinger[dataCenterMap.Count];

            int index = 0;

            foreach (KeyValuePair <string, string> datacenter in dataCenterMap)
            {
                regionPingers[index] = new RegionPinger(datacenter.Value, datacenter.Key, timeoutMs, NumTimeoutsForError, pingsPerRegion);
                index++;
            }

            // initialRegionIndexes are the index of the first region that a ping worker will use. Distribute the
            // indexes such that they are as far apart as possible to reduce the chance of sending all the pings
            // to the same region at the same time

            // Example, if there are 6 regions and 3 pings per region, we will start pinging at regions 0, 2, and 4
            // as shown in the table below

            //        Region 0    Region 1    Region 2    Region 3    Region 4    Region 5
            // Ping 1    x
            // Ping 2                           x
            // Ping 3                                                    x
            //
            ConcurrentBag <int> initialRegionIndexes = new ConcurrentBag <int>(Enumerable.Range(0, pingsPerRegion)
                                                                               .Select(i => i * dataCenterMap.Count / pingsPerRegion));

            Task[] pingWorkers = Enumerable.Range(0, degreeOfParallelism).Select(
                i => PingWorker(regionPingers, initialRegionIndexes)).ToArray();

            await Task.WhenAll(pingWorkers);

            List <QosRegionResult> results = regionPingers.Select(x => x.GetResult()).ToList();

            results.Sort((x, y) => x.LatencyMs.CompareTo(y.LatencyMs));

            QosErrorCode resultCode   = QosErrorCode.Success;
            string       errorMessage = null;

            if (results.All(x => x.ErrorCode == (int)QosErrorCode.NoResult))
            {
                resultCode   = QosErrorCode.NoResult;
                errorMessage = "No valid results from any QoS server";
            }

            return(new QosResult()
            {
                ErrorCode = (int)resultCode,
                RegionResults = results,
                ErrorMessage = errorMessage
            });
        }
        private async Task<List<QosRegionResult>> GetSortedRegionLatencies(int timeoutMs)
        {
            var asyncPingResults = new List<Task<QosRegionResult>>(_dataCenterMap.Count);
            foreach (KeyValuePair<string, string> datacenter in _dataCenterMap)
            {
                var regionPinger = new RegionPinger(datacenter.Value, datacenter.Key);
                Task<QosRegionResult> pingResult = regionPinger.PingAsync(timeoutMs);
                asyncPingResults.Add(pingResult);
            }

            await Task.WhenAll(asyncPingResults);
            var results = new List<QosRegionResult>(asyncPingResults.Count);
            foreach (Task<QosRegionResult> asyncPingResult in asyncPingResults)
            {
                results.Add(asyncPingResult.Result);
            }

            results.Sort((x,y) => x.LatencyMs.CompareTo(y.LatencyMs));

            return results;
        }