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; }