public async Task ReloadStationsAndUpdateTsmAsync() { Logger.TraceLine("Loading stations."); while (true) { bool noaaThrottlingDetected = false; try { await _stationsProcessor.ReloadStationsAsync(); } catch (Exception e) { noaaThrottlingDetected |= Retry.UnwrapAggregateException <NoaaThrottlingDetected>(e) != null; if (!noaaThrottlingDetected) { throw; } } if (noaaThrottlingDetected) { Logger.TraceLine($"Detected NOAA throttling, waiting until {DateTime.Now + DelayOnNoaaThrottling}"); await Task.Delay(DelayOnNoaaThrottling); } else { break; } } Logger.TraceLine($"Loaded {_stationsProcessor.Stations.Length} stations."); var stationObservationProcessors = new Dictionary <string, StationObservationsProcessor>(_stationsProcessor.Stations.Length); foreach (Station station in _stationsProcessor.Stations) { stationObservationProcessors.Add( station.Id, _stationObservationProcessors.ContainsKey(station.Id) ? _stationObservationProcessors[station.Id] : new StationObservationsProcessor(station.ShortId, _noaaClient, _eventHubClient, _stationObservationsCheckpointing)); } _stationObservationProcessors = stationObservationProcessors; Logger.TraceLine("Updating TSM."); if (await _stationsProcessor.UpdateTsmAsync()) { Logger.TraceLine($"Updated TSM for {_stationsProcessor.Stations.Length} stations."); } else { Logger.TraceLine("TSM update skipped."); } }
private async Task <TResult> MakeNoaaApiCall <TResult>( string requestUriString, Func <TextReader, TResult> consumeResponseTextReader) { try { return(await HttpUtils.MakeHttpCallAsync(requestUriString, consumeResponseTextReader, pretendBrowser : true)); } catch (Exception e) { WebException webException = Retry.UnwrapAggregateException <WebException>(e); if (webException != null) { HttpWebResponse response = (HttpWebResponse)webException.Response; if (response != null && response.StatusCode == HttpStatusCode.Forbidden) { throw new NoaaThrottlingDetected(); } } throw; } }
public static async Task <bool> DeleteTableRowIfExistsAsync(CloudTable table, string partitionKey, string rowKey) { TableOperation deleteOperation = TableOperation.Delete(new TableEntity(partitionKey, rowKey) { ETag = "*" }); try { await table.ExecuteAsync(deleteOperation); return(true); } catch (Exception e) { StorageException storageException = Retry.UnwrapAggregateException <StorageException>(e); if (storageException == null || storageException.RequestInformation.HttpStatusCode != 404) { throw; } return(false); } }
public async Task Run() { DateTime?updateStationsTimestamp = null; var tasks = new List <Task>(HttpUtils.DefaultConnectionLimit); int passCount = 1; while (true) { // Make a pass thru all stations. Logger.TraceLine($"PASS {passCount} START"); Stopwatch stopwatch = Stopwatch.StartNew(); if (updateStationsTimestamp == null || DateTime.Now - updateStationsTimestamp > UpdateStationsInterval) { await ReloadStationsAndUpdateTsmAsync(); updateStationsTimestamp = DateTime.Now; } List <StationObservationsProcessor> stationObservationsProcessors = _stationObservationProcessors.Values.ToList(); bool noaaThrottlingDetected = false; while (stationObservationsProcessors.Count > 0 || tasks.Count > 0) { while (stationObservationsProcessors.Count > 0 && tasks.Count < System.Net.ServicePointManager.DefaultConnectionLimit) { StationObservationsProcessor stationObservationsProcessor = stationObservationsProcessors[0]; tasks.Add(stationObservationsProcessor.ProsessStationObservationsAsync()); stationObservationsProcessors.RemoveAt(0); } Task completedTask = await Task.WhenAny(tasks); tasks.Remove(completedTask); try { await completedTask; } catch (Exception e) { noaaThrottlingDetected |= Retry.UnwrapAggregateException <NoaaThrottlingDetected>(e) != null; if (noaaThrottlingDetected) { // Skip remaining work on this pass. stationObservationsProcessors.Clear(); } else { throw; } } } TimeSpan delay; if (noaaThrottlingDetected) { Logger.TraceLine($"PASS {passCount} CANCELLED: Detected NOAA throttling, waiting until {DateTime.Now + DelayOnNoaaThrottling}"); delay = DelayOnNoaaThrottling; } else { Logger.TraceLine($"PASS {passCount} DONE: Elapsed {stopwatch.Elapsed}"); delay = (_stationObservationProcessors.Values.Min(sop => sop.GoodNextTimeToProcess) - DateTime.Now) + TimeSpan.FromMinutes(1); delay = NormalPassDelay > delay ? NormalPassDelay : delay; } ++passCount; Logger.Flush(); await Task.Delay(delay); } }